From 826ebb8d352245a36ecaec32b6af61e7abf4696e Mon Sep 17 00:00:00 2001 From: Diogo Pedrosa Date: Thu, 9 Mar 2023 17:57:35 +0000 Subject: vsomeip 3.3.0 --- .github/workflows/c-cpp.yml | 2 +- AUTHORS | 2 +- Android.bp | 170 +- Android.mk | 214 + CHANGES | 384 +- CMakeLists.txt | 229 +- LICENSE | 2 +- README.md | 34 +- documentation/vsomeipProtocol | 372 ++ documentation/vsomeipUserGuide | 132 +- examples/CMakeLists.txt | 2 - examples/hello_world/Android.bp | 15 +- examples/hello_world/CMakeLists.txt | 13 +- examples/hello_world/readme | 7 +- examples/notify-sample.cpp | 24 +- examples/request-sample.cpp | 2 +- examples/response-sample.cpp | 2 +- examples/routingmanagerd/CMakeLists.txt | 2 - examples/routingmanagerd/routingmanagerd.cpp | 5 +- exportmap.gcc | 15 +- .../compat/runtime/src/application_impl.cpp | 2 +- .../include/application_configuration.hpp | 42 + implementation/configuration/include/client.hpp | 2 +- .../configuration/include/configuration.hpp | 93 +- .../include/configuration_element.hpp | 12 +- .../configuration/include/configuration_impl.hpp | 166 +- .../configuration/include/configuration_plugin.hpp | 12 +- .../include/configuration_plugin_impl.hpp | 9 +- implementation/configuration/include/debounce.hpp | 4 +- implementation/configuration/include/e2e.hpp | 6 +- implementation/configuration/include/event.hpp | 19 +- .../configuration/include/eventgroup.hpp | 2 +- .../configuration/include/internal.hpp.in | 144 +- .../configuration/include/internal_android.hpp | 142 +- implementation/configuration/include/routing.hpp | 71 + implementation/configuration/include/service.hpp | 13 +- .../include/service_instance_range.hpp | 2 +- implementation/configuration/include/trace.hpp | 7 +- implementation/configuration/include/watchdog.hpp | 2 +- .../configuration/src/configuration_impl.cpp | 1155 +++-- .../src/configuration_plugin_impl.cpp | 38 +- .../e2e_protection/include/buffer/buffer.hpp | 2 +- implementation/e2e_protection/include/crc/crc.hpp | 2 +- .../include/e2e/profile/e2e_provider.hpp | 3 +- .../include/e2e/profile/e2e_provider_impl.hpp | 3 +- .../include/e2e/profile/profile01/checker.hpp | 2 +- .../include/e2e/profile/profile01/profile_01.hpp | 2 +- .../include/e2e/profile/profile01/protector.hpp | 2 +- .../include/e2e/profile/profile04/checker.hpp | 10 +- .../include/e2e/profile/profile04/profile_04.hpp | 2 +- .../include/e2e/profile/profile04/protector.hpp | 11 +- .../include/e2e/profile/profile_custom/checker.hpp | 2 +- .../e2e/profile/profile_custom/profile_custom.hpp | 2 +- .../e2e/profile/profile_custom/protector.hpp | 2 +- .../e2e/profile/profile_interface/checker.hpp | 2 +- .../profile_interface/profile_interface.hpp | 4 +- .../e2e/profile/profile_interface/protector.hpp | 2 +- .../e2e_protection/include/e2exf/config.hpp | 2 +- .../e2e_protection/src/buffer/buffer.cpp | 2 +- implementation/e2e_protection/src/crc/crc.cpp | 9 +- .../src/e2e/profile/e2e_provider_impl.cpp | 2 +- .../src/e2e/profile/profile01/checker.cpp | 10 +- .../src/e2e/profile/profile01/profile_01.cpp | 10 +- .../src/e2e/profile/profile01/protector.cpp | 10 +- .../src/e2e/profile/profile04/checker.cpp | 27 +- .../src/e2e/profile/profile04/profile_04.cpp | 11 +- .../src/e2e/profile/profile04/protector.cpp | 32 +- .../src/e2e/profile/profile_custom/checker.cpp | 10 +- .../e2e/profile/profile_custom/profile_custom.cpp | 10 +- .../src/e2e/profile/profile_custom/protector.cpp | 11 +- implementation/e2e_protection/src/e2exf/config.cpp | 2 +- implementation/endpoints/include/buffer.hpp | 49 +- .../endpoints/include/client_endpoint.hpp | 9 +- .../endpoints/include/client_endpoint_impl.hpp | 51 +- implementation/endpoints/include/credentials.hpp | 11 +- implementation/endpoints/include/endpoint.hpp | 19 +- .../endpoints/include/endpoint_definition.hpp | 2 +- implementation/endpoints/include/endpoint_host.hpp | 22 +- implementation/endpoints/include/endpoint_impl.hpp | 12 +- .../endpoints/include/endpoint_manager_base.hpp | 41 +- .../endpoints/include/endpoint_manager_impl.hpp | 73 +- .../include/local_client_endpoint_impl.hpp | 88 - .../include/local_server_endpoint_impl.hpp | 193 - .../local_server_endpoint_impl_receive_op.hpp | 118 + .../include/local_tcp_client_endpoint_impl.hpp | 74 + .../include/local_tcp_server_endpoint_impl.hpp | 166 + .../include/local_uds_client_endpoint_impl.hpp | 73 + .../include/local_uds_server_endpoint_impl.hpp | 191 + .../endpoints/include/netlink_connector.hpp | 36 +- .../endpoints/include/server_endpoint_impl.hpp | 81 +- .../endpoints/include/tcp_client_endpoint_impl.hpp | 15 +- .../endpoints/include/tcp_server_endpoint_impl.hpp | 36 +- implementation/endpoints/include/tp.hpp | 13 +- implementation/endpoints/include/tp_message.hpp | 2 +- .../endpoints/include/tp_reassembler.hpp | 11 +- .../endpoints/include/udp_client_endpoint_impl.hpp | 22 +- .../endpoints/include/udp_server_endpoint_impl.hpp | 48 +- .../udp_server_endpoint_impl_receive_op.hpp | 186 + .../include/virtual_server_endpoint_impl.hpp | 19 +- .../endpoints/src/client_endpoint_impl.cpp | 338 +- implementation/endpoints/src/credentials.cpp | 105 +- .../endpoints/src/endpoint_definition.cpp | 2 +- implementation/endpoints/src/endpoint_impl.cpp | 30 +- .../endpoints/src/endpoint_manager_base.cpp | 267 +- .../endpoints/src/endpoint_manager_impl.cpp | 336 +- .../endpoints/src/local_client_endpoint_impl.cpp | 413 -- .../endpoints/src/local_server_endpoint_impl.cpp | 993 ----- .../src/local_tcp_client_endpoint_impl.cpp | 382 ++ .../src/local_tcp_server_endpoint_impl.cpp | 897 ++++ .../src/local_uds_client_endpoint_impl.cpp | 383 ++ .../src/local_uds_server_endpoint_impl.cpp | 1067 +++++ implementation/endpoints/src/netlink_connector.cpp | 65 +- .../endpoints/src/server_endpoint_impl.cpp | 529 ++- .../endpoints/src/tcp_client_endpoint_impl.cpp | 99 +- .../endpoints/src/tcp_server_endpoint_impl.cpp | 171 +- implementation/endpoints/src/tp.cpp | 19 +- implementation/endpoints/src/tp_message.cpp | 4 +- implementation/endpoints/src/tp_reassembler.cpp | 5 +- .../endpoints/src/udp_client_endpoint_impl.cpp | 96 +- .../endpoints/src/udp_server_endpoint_impl.cpp | 617 +-- .../endpoints/src/virtual_server_endpoint_impl.cpp | 20 +- .../1.55/boost/asio/basic_datagram_socket_ext.hpp | 954 ----- .../1.55/boost/asio/basic_socket_acceptor_ext.hpp | 1139 ----- .../1.55/boost/asio/basic_stream_socket_ext.hpp | 855 ---- .../boost/asio/datagram_socket_service_ext.hpp | 437 -- .../asio/detail/handler_type_requirements_ext.hpp | 520 --- .../detail/handler_type_requirements_ext_local.hpp | 536 --- .../impl/reactive_socket_service_base_ext.ipp | 270 -- .../reactive_socket_service_base_ext_local.ipp | 270 -- .../1.55/boost/asio/detail/impl/socket_ops_ext.ipp | 230 - .../asio/detail/impl/socket_ops_ext_local.ipp | 302 -- .../asio/detail/reactive_socket_recv_op_ext.hpp | 126 - .../detail/reactive_socket_recv_op_ext_local.hpp | 126 - .../detail/reactive_socket_recvfrom_op_ext.hpp | 136 - .../reactive_socket_recvfrom_op_ext_local.hpp | 136 - .../asio/detail/reactive_socket_recvmsg_op_ext.hpp | 128 - .../reactive_socket_recvmsg_op_ext_local.hpp | 128 - .../detail/reactive_socket_service_base_ext.hpp | 455 -- .../reactive_socket_service_base_ext_local.hpp | 454 -- .../asio/detail/reactive_socket_service_ext.hpp | 462 -- .../detail/reactive_socket_service_ext_local.hpp | 462 -- .../1.55/boost/asio/detail/reactor_op_ext.hpp | 42 - .../boost/asio/detail/reactor_op_ext_local.hpp | 43 - .../1.55/boost/asio/detail/socket_ops_ext.hpp | 62 - .../boost/asio/detail/socket_ops_ext_local.hpp | 72 - .../helper/1.55/boost/asio/ip/udp_ext.hpp | 115 - .../1.55/boost/asio/local/stream_protocol_ext.hpp | 93 - .../boost/asio/socket_acceptor_service_ext.hpp | 305 -- .../1.55/boost/asio/stream_socket_service_ext.hpp | 379 -- .../1.66/boost/asio/basic_datagram_socket_ext.hpp | 1043 ----- .../1.66/boost/asio/basic_socket_acceptor_ext.hpp | 1989 --------- .../helper/1.66/boost/asio/basic_socket_ext.hpp | 1760 -------- .../1.66/boost/asio/basic_socket_ext_local.hpp | 1760 -------- .../1.66/boost/asio/basic_stream_socket_ext.hpp | 924 ---- .../asio/detail/handler_type_requirements_ext.hpp | 565 --- .../detail/handler_type_requirements_ext_local.hpp | 592 --- .../impl/reactive_socket_service_base_ext.ipp | 302 -- .../reactive_socket_service_base_ext_local.ipp | 302 -- .../1.66/boost/asio/detail/impl/socket_ops_ext.ipp | 230 - .../asio/detail/impl/socket_ops_ext_local.ipp | 302 -- .../asio/detail/reactive_socket_recv_op_ext.hpp | 138 - .../detail/reactive_socket_recv_op_ext_local.hpp | 138 - .../detail/reactive_socket_recvfrom_op_ext.hpp | 141 - .../reactive_socket_recvfrom_op_ext_local.hpp | 141 - .../asio/detail/reactive_socket_recvmsg_op_ext.hpp | 135 - .../reactive_socket_recvmsg_op_ext_local.hpp | 135 - .../detail/reactive_socket_service_base_ext.hpp | 517 --- .../reactive_socket_service_base_ext_local.hpp | 514 --- .../asio/detail/reactive_socket_service_ext.hpp | 531 --- .../detail/reactive_socket_service_ext_local.hpp | 529 --- .../1.66/boost/asio/detail/reactor_op_ext.hpp | 42 - .../boost/asio/detail/reactor_op_ext_local.hpp | 47 - .../1.66/boost/asio/detail/socket_ops_ext.hpp | 62 - .../boost/asio/detail/socket_ops_ext_local.hpp | 95 - .../helper/1.66/boost/asio/ip/udp_ext.hpp | 115 - .../1.66/boost/asio/local/stream_protocol_ext.hpp | 93 - .../1.66/boost/asio/stream_socket_service_ext.hpp | 415 -- .../1.70/boost/asio/basic_datagram_socket_ext.hpp | 1118 ----- .../1.70/boost/asio/basic_socket_acceptor_ext.hpp | 2381 ----------- .../helper/1.70/boost/asio/basic_socket_ext.hpp | 1859 --------- .../1.70/boost/asio/basic_socket_ext_local.hpp | 1859 --------- .../1.70/boost/asio/basic_stream_socket_ext.hpp | 996 ----- .../asio/detail/handler_type_requirements_ext.hpp | 586 --- .../detail/handler_type_requirements_ext_local.hpp | 588 --- .../impl/reactive_socket_service_base_ext.ipp | 302 -- .../reactive_socket_service_base_ext_local.ipp | 302 -- .../1.70/boost/asio/detail/impl/socket_ops_ext.ipp | 230 - .../asio/detail/impl/socket_ops_ext_local.ipp | 303 -- .../asio/detail/reactive_socket_recv_op_ext.hpp | 140 - .../detail/reactive_socket_recv_op_ext_local.hpp | 140 - .../detail/reactive_socket_recvfrom_op_ext.hpp | 145 - .../reactive_socket_recvfrom_op_ext_local.hpp | 145 - .../asio/detail/reactive_socket_recvmsg_op_ext.hpp | 138 - .../reactive_socket_recvmsg_op_ext_local.hpp | 138 - .../detail/reactive_socket_service_base_ext.hpp | 521 --- .../reactive_socket_service_base_ext_local.hpp | 521 --- .../asio/detail/reactive_socket_service_ext.hpp | 508 --- .../detail/reactive_socket_service_ext_local.hpp | 508 --- .../1.70/boost/asio/detail/reactor_op_ext.hpp | 42 - .../boost/asio/detail/reactor_op_ext_local.hpp | 43 - .../1.70/boost/asio/detail/socket_ops_ext.hpp | 62 - .../boost/asio/detail/socket_ops_ext_local.hpp | 95 - .../helper/1.70/boost/asio/ip/udp_ext.hpp | 115 - .../1.70/boost/asio/local/stream_protocol_ext.hpp | 93 - .../1.74/boost/asio/basic_datagram_socket_ext.hpp | 1118 ----- .../1.74/boost/asio/basic_socket_acceptor_ext.hpp | 2381 ----------- .../helper/1.74/boost/asio/basic_socket_ext.hpp | 1859 --------- .../1.74/boost/asio/basic_socket_ext_local.hpp | 1859 --------- .../1.74/boost/asio/basic_stream_socket_ext.hpp | 996 ----- .../asio/detail/handler_type_requirements_ext.hpp | 586 --- .../detail/handler_type_requirements_ext_local.hpp | 588 --- .../impl/reactive_socket_service_base_ext.ipp | 302 -- .../reactive_socket_service_base_ext_local.ipp | 302 -- .../1.74/boost/asio/detail/impl/socket_ops_ext.ipp | 234 -- .../asio/detail/impl/socket_ops_ext_local.ipp | 307 -- .../asio/detail/reactive_socket_recv_op_ext.hpp | 162 - .../detail/reactive_socket_recv_op_ext_local.hpp | 162 - .../detail/reactive_socket_recvfrom_op_ext.hpp | 153 - .../reactive_socket_recvfrom_op_ext_local.hpp | 148 - .../asio/detail/reactive_socket_recvmsg_op_ext.hpp | 144 - .../reactive_socket_recvmsg_op_ext_local.hpp | 145 - .../detail/reactive_socket_service_base_ext.hpp | 524 --- .../reactive_socket_service_base_ext_local.hpp | 524 --- .../asio/detail/reactive_socket_service_ext.hpp | 508 --- .../detail/reactive_socket_service_ext_local.hpp | 508 --- .../1.74/boost/asio/detail/reactor_op_ext.hpp | 43 - .../boost/asio/detail/reactor_op_ext_local.hpp | 44 - .../1.74/boost/asio/detail/socket_ops_ext.hpp | 62 - .../boost/asio/detail/socket_ops_ext_local.hpp | 95 - .../helper/1.74/boost/asio/ip/udp_ext.hpp | 115 - .../1.74/boost/asio/local/stream_protocol_ext.hpp | 93 - .../1.76/boost/asio/basic_datagram_socket_ext.hpp | 1118 ----- .../1.76/boost/asio/basic_socket_acceptor_ext.hpp | 2381 ----------- .../helper/1.76/boost/asio/basic_socket_ext.hpp | 1859 --------- .../1.76/boost/asio/basic_socket_ext_local.hpp | 1859 --------- .../1.76/boost/asio/basic_stream_socket_ext.hpp | 996 ----- .../asio/detail/handler_type_requirements_ext.hpp | 586 --- .../detail/handler_type_requirements_ext_local.hpp | 588 --- .../impl/reactive_socket_service_base_ext.ipp | 302 -- .../reactive_socket_service_base_ext_local.ipp | 302 -- .../1.76/boost/asio/detail/impl/socket_ops_ext.ipp | 234 -- .../asio/detail/impl/socket_ops_ext_local.ipp | 307 -- .../asio/detail/reactive_socket_recv_op_ext.hpp | 162 - .../detail/reactive_socket_recv_op_ext_local.hpp | 162 - .../detail/reactive_socket_recvfrom_op_ext.hpp | 153 - .../reactive_socket_recvfrom_op_ext_local.hpp | 148 - .../asio/detail/reactive_socket_recvmsg_op_ext.hpp | 144 - .../reactive_socket_recvmsg_op_ext_local.hpp | 145 - .../detail/reactive_socket_service_base_ext.hpp | 524 --- .../reactive_socket_service_base_ext_local.hpp | 524 --- .../asio/detail/reactive_socket_service_ext.hpp | 508 --- .../detail/reactive_socket_service_ext_local.hpp | 508 --- .../1.76/boost/asio/detail/reactor_op_ext.hpp | 43 - .../boost/asio/detail/reactor_op_ext_local.hpp | 44 - .../1.76/boost/asio/detail/socket_ops_ext.hpp | 62 - .../boost/asio/detail/socket_ops_ext_local.hpp | 95 - .../helper/1.76/boost/asio/ip/udp_ext.hpp | 115 - .../1.76/boost/asio/local/stream_protocol_ext.hpp | 93 - .../boost/asio/basic_datagram_socket_ext.hpp | 954 +++++ .../boost/asio/basic_socket_acceptor_ext.hpp | 1139 +++++ .../helper/boost/asio/basic_stream_socket_ext.hpp | 855 ++++ .../boost/asio/datagram_socket_service_ext.hpp | 437 ++ .../asio/detail/handler_type_requirements_ext.hpp | 520 +++ .../detail/handler_type_requirements_ext_local.hpp | 536 +++ .../impl/reactive_socket_service_base_ext.ipp | 270 ++ .../reactive_socket_service_base_ext_local.ipp | 270 ++ .../boost/asio/detail/impl/socket_ops_ext.ipp | 210 + .../asio/detail/impl/socket_ops_ext_local.ipp | 302 ++ .../asio/detail/reactive_socket_recv_op_ext.hpp | 126 + .../detail/reactive_socket_recv_op_ext_local.hpp | 126 + .../detail/reactive_socket_recvfrom_op_ext.hpp | 136 + .../reactive_socket_recvfrom_op_ext_local.hpp | 136 + .../asio/detail/reactive_socket_recvmsg_op_ext.hpp | 128 + .../reactive_socket_recvmsg_op_ext_local.hpp | 128 + .../detail/reactive_socket_service_base_ext.hpp | 455 ++ .../reactive_socket_service_base_ext_local.hpp | 454 ++ .../asio/detail/reactive_socket_service_ext.hpp | 462 ++ .../detail/reactive_socket_service_ext_local.hpp | 462 ++ .../helper/boost/asio/detail/reactor_op_ext.hpp | 42 + .../boost/asio/detail/reactor_op_ext_local.hpp | 43 + .../helper/boost/asio/detail/socket_ops_ext.hpp | 62 + .../boost/asio/detail/socket_ops_ext_local.hpp | 72 + implementation/helper/boost/asio/ip/udp_ext.hpp | 115 + .../boost/asio/local/stream_protocol_ext.hpp | 93 + .../boost/asio/socket_acceptor_service_ext.hpp | 305 ++ .../boost/asio/stream_socket_service_ext.hpp | 379 ++ implementation/logger/include/logger_impl.hpp | 8 +- implementation/logger/src/logger_impl.cpp | 17 +- implementation/logger/src/message.cpp | 100 +- implementation/message/include/deserializer.hpp | 3 +- .../message/include/message_base_impl.hpp | 2 +- .../message/include/message_header_impl.hpp | 2 +- implementation/message/include/message_impl.hpp | 14 +- implementation/message/include/payload_impl.hpp | 2 +- implementation/message/include/serializer.hpp | 9 +- implementation/message/src/deserializer.cpp | 29 +- implementation/message/src/message_base_impl.cpp | 2 +- implementation/message/src/message_header_impl.cpp | 2 +- implementation/message/src/message_impl.cpp | 44 +- implementation/message/src/payload_impl.cpp | 2 +- implementation/message/src/serializer.cpp | 2 +- implementation/plugin/include/plugin_manager.hpp | 8 +- .../plugin/include/plugin_manager_impl.hpp | 12 +- implementation/plugin/src/plugin_manager.cpp | 2 +- implementation/plugin/src/plugin_manager_impl.cpp | 70 +- .../protocol/include/assign_client_ack_command.hpp | 33 + .../protocol/include/assign_client_command.hpp | 38 + implementation/protocol/include/command.hpp | 46 + .../include/deregister_application_command.hpp | 24 + .../distribute_security_policies_command.hpp | 44 + implementation/protocol/include/dummy_command.hpp | 28 + implementation/protocol/include/expire_command.hpp | 33 + .../include/multiple_services_command_base.hpp | 37 + .../protocol/include/offer_service_command.hpp | 24 + .../include/offered_services_request_command.hpp | 33 + .../include/offered_services_response_command.hpp | 23 + implementation/protocol/include/ping_command.hpp | 24 + implementation/protocol/include/pong_command.hpp | 24 + implementation/protocol/include/protocol.hpp | 142 + .../include/register_application_command.hpp | 33 + implementation/protocol/include/register_event.hpp | 67 + .../protocol/include/register_events_command.hpp | 40 + .../protocol/include/registered_ack_command.hpp | 24 + .../protocol/include/release_service_command.hpp | 39 + .../include/remove_security_policy_command.hpp | 41 + .../remove_security_policy_response_command.hpp | 24 + .../protocol/include/request_service_command.hpp | 23 + .../include/resend_provided_events_command.hpp | 33 + .../protocol/include/routing_info_command.hpp | 36 + .../protocol/include/routing_info_entry.hpp | 59 + .../security_policy_response_command_base.hpp | 38 + implementation/protocol/include/send_command.hpp | 52 + .../protocol/include/service_command_base.hpp | 45 + implementation/protocol/include/simple_command.hpp | 30 + .../include/stop_offer_service_command.hpp | 24 + .../protocol/include/subscribe_ack_command.hpp | 24 + .../include/subscribe_ack_command_base.hpp | 57 + .../protocol/include/subscribe_command.hpp | 39 + .../protocol/include/subscribe_command_base.hpp | 59 + .../protocol/include/subscribe_nack_command.hpp | 24 + .../protocol/include/suspend_command.hpp | 24 + .../protocol/include/unregister_event_command.hpp | 49 + .../protocol/include/unsubscribe_ack_command.hpp | 47 + .../protocol/include/unsubscribe_command.hpp | 33 + .../update_security_credentials_command.hpp | 39 + .../include/update_security_policy_command.hpp | 42 + .../update_security_policy_response_command.hpp | 24 + .../protocol/src/assign_client_ack_command.cpp | 79 + .../protocol/src/assign_client_command.cpp | 83 + implementation/protocol/src/command.cpp | 66 + .../src/deregister_application_command.cpp | 19 + .../src/distribute_security_policies_command.cpp | 130 + implementation/protocol/src/dummy_command.cpp | 40 + implementation/protocol/src/expire_command.cpp | 64 + .../src/multiple_services_command_base.cpp | 119 + .../protocol/src/offer_service_command.cpp | 17 + .../src/offered_services_request_command.cpp | 78 + .../src/offered_services_response_command.cpp | 17 + implementation/protocol/src/ping_command.cpp | 17 + implementation/protocol/src/pong_command.cpp | 17 + .../protocol/src/register_application_command.cpp | 81 + implementation/protocol/src/register_event.cpp | 82 + .../protocol/src/register_events_command.cpp | 110 + .../protocol/src/registered_ack_command.cpp | 17 + .../protocol/src/release_service_command.cpp | 101 + .../src/remove_security_policy_command.cpp | 114 + .../remove_security_policy_response_command.cpp | 18 + .../protocol/src/request_service_command.cpp | 17 + .../src/resend_provided_events_command.cpp | 80 + .../protocol/src/routing_info_command.cpp | 98 + implementation/protocol/src/routing_info_entry.cpp | 304 ++ .../src/security_policy_response_command_base.cpp | 80 + implementation/protocol/src/send_command.cpp | 149 + .../protocol/src/service_command_base.cpp | 130 + implementation/protocol/src/simple_command.cpp | 48 + .../protocol/src/stop_offer_service_command.cpp | 17 + .../protocol/src/subscribe_ack_command.cpp | 17 + .../protocol/src/subscribe_ack_command_base.cpp | 174 + implementation/protocol/src/subscribe_command.cpp | 144 + .../protocol/src/subscribe_command_base.cpp | 146 + .../protocol/src/subscribe_nack_command.cpp | 17 + implementation/protocol/src/suspend_command.cpp | 17 + .../protocol/src/unregister_event_command.cpp | 135 + .../protocol/src/unsubscribe_ack_command.cpp | 139 + .../protocol/src/unsubscribe_command.cpp | 64 + .../src/update_security_credentials_command.cpp | 103 + .../src/update_security_policy_command.cpp | 120 + .../update_security_policy_response_command.cpp | 18 + implementation/routing/include/event.hpp | 50 +- implementation/routing/include/eventgroupinfo.hpp | 4 +- implementation/routing/include/function_types.hpp | 7 +- .../routing/include/remote_subscription.hpp | 3 +- implementation/routing/include/routing_host.hpp | 13 +- implementation/routing/include/routing_manager.hpp | 43 +- .../routing/include/routing_manager_adapter.hpp | 2 +- .../routing/include/routing_manager_base.hpp | 126 +- .../routing/include/routing_manager_client.hpp | 298 ++ .../routing/include/routing_manager_host.hpp | 30 +- .../routing/include/routing_manager_impl.hpp | 155 +- .../routing/include/routing_manager_proxy.hpp | 267 -- .../routing/include/routing_manager_stub.hpp | 136 +- .../routing/include/routing_manager_stub_host.hpp | 96 +- implementation/routing/include/serviceinfo.hpp | 8 +- implementation/routing/include/types.hpp | 18 +- implementation/routing/src/event.cpp | 615 ++- implementation/routing/src/eventgroupinfo.cpp | 72 +- implementation/routing/src/remote_subscription.cpp | 3 +- .../routing/src/routing_manager_base.cpp | 346 +- .../routing/src/routing_manager_client.cpp | 2890 +++++++++++++ .../routing/src/routing_manager_impl.cpp | 1160 ++++-- .../routing/src/routing_manager_proxy.cpp | 2734 ------------ .../routing/src/routing_manager_stub.cpp | 2550 ++++++------ implementation/routing/src/serviceinfo.cpp | 14 +- .../runtime/include/application_impl.hpp | 117 +- implementation/runtime/include/runtime_impl.hpp | 4 +- implementation/runtime/src/application_impl.cpp | 837 ++-- implementation/runtime/src/runtime.cpp | 21 +- implementation/runtime/src/runtime_impl.cpp | 17 +- implementation/security/include/policy.hpp | 2 +- .../security/include/policy_manager_impl.hpp | 177 +- implementation/security/include/security.hpp | 73 +- implementation/security/include/security_impl.hpp | 114 - implementation/security/src/policy.cpp | 9 +- implementation/security/src/policy_manager.cpp | 6 +- .../security/src/policy_manager_impl.cpp | 1446 ++++++- implementation/security/src/security.cpp | 140 +- implementation/security/src/security_impl.cpp | 1196 ------ .../include/configuration_option_impl.hpp | 4 +- .../service_discovery/include/constants.hpp | 2 +- .../service_discovery/include/defines.hpp | 4 +- .../service_discovery/include/deserializer.hpp | 2 +- .../service_discovery/include/entry_impl.hpp | 2 +- .../include/enumeration_types.hpp | 2 +- .../include/eventgroupentry_impl.hpp | 2 +- .../service_discovery/include/ip_option_impl.hpp | 4 +- .../service_discovery/include/ipv4_option_impl.hpp | 10 +- .../service_discovery/include/ipv6_option_impl.hpp | 4 +- .../include/load_balancing_option_impl.hpp | 4 +- .../include/message_element_impl.hpp | 2 +- .../service_discovery/include/message_impl.hpp | 10 +- .../service_discovery/include/option_impl.hpp | 5 +- .../service_discovery/include/primitive_types.hpp | 12 +- .../include/protection_option_impl.hpp | 4 +- .../include/remote_subscription_ack.hpp | 2 +- .../service_discovery/include/request.hpp | 2 +- .../service_discovery/include/runtime.hpp | 2 +- .../service_discovery/include/runtime_impl.hpp | 2 +- .../include/selective_option_impl.hpp | 4 +- .../include/service_discovery.hpp | 14 +- .../include/service_discovery_host.hpp | 16 +- .../include/service_discovery_impl.hpp | 49 +- .../include/serviceentry_impl.hpp | 2 +- .../service_discovery/include/subscription.hpp | 2 +- .../src/configuration_option_impl.cpp | 8 +- .../service_discovery/src/deserializer.cpp | 2 +- .../service_discovery/src/entry_impl.cpp | 2 +- .../service_discovery/src/eventgroupentry_impl.cpp | 14 +- .../service_discovery/src/ip_option_impl.cpp | 6 +- .../service_discovery/src/ipv4_option_impl.cpp | 6 +- .../service_discovery/src/ipv6_option_impl.cpp | 6 +- .../src/load_balancing_option_impl.cpp | 6 +- .../service_discovery/src/message_element_impl.cpp | 2 +- .../service_discovery/src/message_impl.cpp | 19 +- .../service_discovery/src/option_impl.cpp | 10 +- .../src/protection_option_impl.cpp | 6 +- .../src/remote_subscription_ack.cpp | 2 +- implementation/service_discovery/src/request.cpp | 2 +- .../service_discovery/src/runtime_impl.cpp | 2 +- .../src/selective_option_impl.cpp | 6 +- .../src/service_discovery_impl.cpp | 292 +- .../service_discovery/src/serviceentry_impl.cpp | 2 +- .../service_discovery/src/subscription.cpp | 4 +- implementation/tracing/include/channel_impl.hpp | 23 +- implementation/tracing/include/connector_impl.hpp | 10 +- implementation/tracing/include/defines.hpp | 2 +- .../tracing/include/enumeration_types.hpp | 5 +- implementation/tracing/include/header.hpp | 2 +- implementation/tracing/src/channel_impl.cpp | 82 +- implementation/tracing/src/connector_impl.cpp | 112 +- implementation/tracing/src/header.cpp | 2 +- implementation/utility/include/byteorder.hpp | 12 +- implementation/utility/include/criticalsection.hpp | 2 +- implementation/utility/include/utility.hpp | 83 +- implementation/utility/src/criticalsection.cpp | 2 +- implementation/utility/src/utility.cpp | 173 +- implementation/utility/src/wrappers.cpp | 38 + interface/compat/vsomeip/constants.hpp | 2 +- interface/compat/vsomeip/primitive_types.hpp | 2 +- interface/compat/vsomeip/trace.hpp | 40 +- interface/vsomeip/application.hpp | 266 +- interface/vsomeip/constants.hpp | 5 +- interface/vsomeip/defines.hpp | 61 +- interface/vsomeip/deprecated.hpp | 10 + interface/vsomeip/enumeration_types.hpp | 9 +- interface/vsomeip/error.hpp | 2 +- interface/vsomeip/function_types.hpp | 2 +- interface/vsomeip/handler.hpp | 28 +- interface/vsomeip/internal/deserializable.hpp | 2 +- interface/vsomeip/internal/logger.hpp | 2 +- interface/vsomeip/internal/policy_manager.hpp | 8 +- interface/vsomeip/internal/serializable.hpp | 2 +- interface/vsomeip/message.hpp | 18 +- interface/vsomeip/message_base.hpp | 2 +- interface/vsomeip/payload.hpp | 2 +- interface/vsomeip/plugin.hpp | 15 +- interface/vsomeip/plugins/application_plugin.hpp | 2 +- .../vsomeip/plugins/pre_configuration_plugin.hpp | 2 +- interface/vsomeip/primitive_types.hpp | 7 +- interface/vsomeip/runtime.hpp | 22 +- interface/vsomeip/structured_types.hpp | 66 + interface/vsomeip/trace.hpp | 2 +- interface/vsomeip/vsomeip.hpp | 2 +- interface/vsomeip/vsomeip_sec.h | 158 + libvsomeip.yaml | 6 + test/CMakeLists.txt | 3832 +---------------- test/application_tests/application_test.cpp | 479 --- .../application_test_availability.cpp | 39 - .../application_test_availability_starter.sh | 10 - test/application_tests/application_test_client.cpp | 199 - .../application_test_client_availability.cpp | 203 - test/application_tests/application_test_daemon.cpp | 42 - .../application_tests/application_test_globals.hpp | 28 - .../application_tests/application_test_service.cpp | 128 - .../application_test_single_process.cpp | 47 - .../application_test_single_process.json | 14 - .../application_test_single_process_starter.sh | 23 - test/application_tests/application_test_starter.sh | 61 - .../conf/application_test.json.in | 38 - .../conf/application_test_daemon.json.in | 38 - .../application_test_no_dispatch_threads.json.in | 37 - ...ication_test_no_dispatch_threads_daemon.json.in | 37 - test/benchmark_tests/CMakeLists.txt | 30 + test/benchmark_tests/main.cpp | 8 + .../security_tests/bm_check_credentials.cpp | 106 + .../bm_check_routing_credentials.cpp | 99 + .../bm_get_client_to_sec_client_mapping.cpp | 61 + .../security_tests/bm_get_clients.cpp | 52 + .../bm_get_sec_client_to_clients_mapping.cpp | 60 + .../security_tests/bm_is_client_allowed.cpp | 195 + .../security_tests/bm_is_offer_allowed.cpp | 167 + .../security_tests/bm_is_policy_update_allowed.cpp | 358 ++ .../security_tests/bm_load_policies.cpp | 98 + .../bm_load_security_update_whitelist.cpp | 144 + .../bm_remove_client_to_sec_client_mapping.cpp | 52 + .../security_tests/bm_remove_security_policy.cpp | 61 + test/big_payload_tests/big_payload_test_client.cpp | 303 -- test/big_payload_tests/big_payload_test_client.hpp | 52 - .../big_payload_test_client_local_start.sh | 10 - .../big_payload_test_client_start.sh | 10 - .../big_payload_test_external_starter.sh | 83 - .../big_payload_tests/big_payload_test_globals.hpp | 43 - test/big_payload_tests/big_payload_test_local.json | 56 - .../big_payload_test_local_limited.json | 44 - .../big_payload_test_local_queue_limited.json | 44 - .../big_payload_test_local_random.json | 44 - .../big_payload_test_local_starter.sh | 52 - .../big_payload_tests/big_payload_test_service.cpp | 275 -- .../big_payload_tests/big_payload_test_service.hpp | 51 - .../big_payload_test_service_external_start.sh | 28 - .../big_payload_test_service_local_start.sh | 10 - .../conf/big_payload_test_tcp_client.json.in | 43 - ...payload_test_tcp_client_limited_general.json.in | 31 - ...d_test_tcp_client_queue_limited_general.json.in | 31 - ..._test_tcp_client_queue_limited_specific.json.in | 43 - .../big_payload_test_tcp_client_random.json.in | 32 - .../conf/big_payload_test_tcp_service.json.in | 81 - ...ayload_test_tcp_service_limited_general.json.in | 69 - ..._test_tcp_service_queue_limited_general.json.in | 87 - ...test_tcp_service_queue_limited_specific.json.in | 99 - .../big_payload_test_tcp_service_random.json.in | 70 - .../conf/big_payload_test_udp_client.json.in | 44 - .../conf/big_payload_test_udp_service.json.in | 41 - test/client_id_tests/client_id_test_globals.hpp | 34 - .../client_id_test_master_starter.sh | 83 - test/client_id_tests/client_id_test_service.cpp | 292 -- .../client_id_test_slave_starter.sh | 50 - test/client_id_tests/client_id_test_utility.cpp | 608 --- test/client_id_tests/client_id_test_utility.json | 35 - ...t_id_test_utility_discontinuous_masked_511.json | 36 - .../client_id_test_utility_masked_127.json | 36 - .../client_id_test_utility_masked_4095.json | 36 - .../client_id_test_utility_masked_511.json | 36 - ..._test_diff_client_ids_diff_ports_master.json.in | 70 - ...d_test_diff_client_ids_diff_ports_slave.json.in | 70 - ...ff_client_ids_partial_same_ports_master.json.in | 70 - ...iff_client_ids_partial_same_ports_slave.json.in | 70 - ..._test_diff_client_ids_same_ports_master.json.in | 70 - ...d_test_diff_client_ids_same_ports_slave.json.in | 70 - ..._test_same_client_ids_diff_ports_master.json.in | 70 - ...d_test_same_client_ids_diff_ports_slave.json.in | 70 - ..._test_same_client_ids_same_ports_master.json.in | 70 - ...d_test_same_client_ids_same_ports_slave.json.in | 70 - .../vsomeip/0_0/vsomeip_security.json | 255 ++ .../vsomeip/4002200_4002200/vsomeip_security.json | 1556 +++++++ .../vsomeip/4002201_4002201/vsomeip_security.json | 122 + .../vsomeip/4002205_4002205/vsomeip_security.json | 54 + .../vsomeip/4003013_4003011/vsomeip_security.json | 64 + .../vsomeip/4003014_4003014/vsomeip_security.json | 1306 ++++++ .../vsomeip/4003015_4003015/vsomeip_security.json | 82 + .../vsomeip/4003016_4003016/vsomeip_security.json | 63 + .../vsomeip/vsomeip_policy_extensions.json | 1 + .../vsomeip/vsomeip_security.json | 25 + test/common/utility.cpp | 235 ++ test/common/utility.hpp | 77 + .../configuration-test-deprecated.json | 496 --- test/configuration_tests/configuration-test.cpp | 811 ---- test/configuration_tests/configuration-test.json | 492 --- .../conf/cpu_load_test_client_master.json.in | 38 - .../conf/cpu_load_test_client_slave.json.in | 38 - .../conf/cpu_load_test_service_master.json.in | 51 - .../conf/cpu_load_test_service_slave.json.in | 51 - test/cpu_load_tests/cpu_load_measurer.cpp | 159 - test/cpu_load_tests/cpu_load_measurer.hpp | 35 - test/cpu_load_tests/cpu_load_test_client.cpp | 390 -- test/cpu_load_tests/cpu_load_test_globals.hpp | 18 - .../cpu_load_tests/cpu_load_test_master_starter.sh | 78 - test/cpu_load_tests/cpu_load_test_service.cpp | 209 - test/cpu_load_tests/cpu_load_test_slave_starter.sh | 52 - test/debounce_tests/debounce_test_client.json | 52 - test/debounce_tests/debounce_test_service.json | 19 - .../e2e_profile_04_test_client_external.json.in | 56 - .../e2e_profile_04_test_service_external.json.in | 57 - .../conf/e2e_test_client_external.json.in | 83 - .../conf/e2e_test_service_external.json.in | 66 - test/e2e_tests/e2e_profile_04_test_client.cpp | 313 -- test/e2e_tests/e2e_profile_04_test_client.hpp | 48 - test/e2e_tests/e2e_profile_04_test_common.hpp | 24 - .../e2e_profile_04_test_external_master_start.sh | 74 - .../e2e_profile_04_test_external_slave_start.sh | 45 - test/e2e_tests/e2e_profile_04_test_service.cpp | 324 -- test/e2e_tests/e2e_profile_04_test_service.hpp | 48 - test/e2e_tests/e2e_test_client.cpp | 387 -- test/e2e_tests/e2e_test_client.hpp | 55 - test/e2e_tests/e2e_test_external_master_start.sh | 74 - test/e2e_tests/e2e_test_external_slave_start.sh | 45 - test/e2e_tests/e2e_test_service.cpp | 300 -- test/e2e_tests/e2e_test_service.hpp | 44 - test/event_tests/conf/event_test_master.json.in | 32 - test/event_tests/conf/event_test_slave_tcp.json.in | 43 - test/event_tests/conf/event_test_slave_udp.json.in | 40 - test/event_tests/event_test_client.cpp | 282 -- test/event_tests/event_test_globals.hpp | 33 - test/event_tests/event_test_master_starter.sh | 64 - test/event_tests/event_test_service.cpp | 201 - test/event_tests/event_test_slave_starter.sh | 44 - test/header_factory_tests/header_factory_test.cpp | 119 - .../header_factory_test_client.cpp | 170 - .../header_factory_test_client.hpp | 48 - .../header_factory_test_client.json | 97 - .../header_factory_test_client_start.sh | 8 - .../header_factory_test_send_receive_starter.sh | 39 - .../header_factory_test_service.cpp | 170 - .../header_factory_test_service.hpp | 45 - .../header_factory_test_service.json | 105 - .../header_factory_test_service_start.sh | 9 - ..._test_diff_client_ids_diff_ports_master.json.in | 81 - ...t_diff_client_ids_diff_ports_master_tcp.json.in | 78 - ...t_diff_client_ids_diff_ports_master_udp.json.in | 66 - ...t_ids_diff_ports_same_service_id_master.json.in | 81 - ...nt_ids_diff_ports_same_service_id_slave.json.in | 82 - ...t_test_diff_client_ids_diff_ports_slave.json.in | 82 - ...st_diff_client_ids_diff_ports_slave_tcp.json.in | 79 - ...st_diff_client_ids_diff_ports_slave_udp.json.in | 67 - ...ff_client_ids_partial_same_ports_master.json.in | 81 - ...iff_client_ids_partial_same_ports_slave.json.in | 82 - ..._test_diff_client_ids_same_ports_master.json.in | 81 - ...t_diff_client_ids_same_ports_master_tcp.json.in | 78 - ...t_diff_client_ids_same_ports_master_udp.json.in | 66 - ...t_test_diff_client_ids_same_ports_slave.json.in | 82 - ...st_diff_client_ids_same_ports_slave_tcp.json.in | 79 - ...st_diff_client_ids_same_ports_slave_udp.json.in | 67 - ..._test_same_client_ids_diff_ports_master.json.in | 81 - ...t_test_same_client_ids_diff_ports_slave.json.in | 82 - ..._test_same_client_ids_same_ports_master.json.in | 81 - ...t_test_same_client_ids_same_ports_slave.json.in | 82 - .../initial_event_test_availability_checker.cpp | 165 - .../initial_event_test_client.cpp | 638 --- .../initial_event_test_globals.hpp | 51 - .../initial_event_test_master_starter.sh | 146 - .../initial_event_test_service.cpp | 171 - .../initial_event_test_slave_starter.sh | 104 - .../initial_event_test_stop_service.cpp | 286 -- .../CMakeLists.txt | 37 + .../applet.cpp | 44 + .../applet.hpp | 22 + .../client.cpp | 152 + .../client.hpp | 24 + .../config.hpp | 12 + .../main.cpp | 43 + .../server.cpp | 132 + .../server.hpp | 24 + .../vsomeip.json | 35 + .../conf/magic_cookies_test_client.json.in | 85 - .../conf/magic_cookies_test_service.json.in | 88 - .../magic_cookies_test_client.cpp | 246 -- .../magic_cookies_test_client_start.sh | 9 - .../magic_cookies_test_service.cpp | 168 - .../magic_cookies_test_service_start.sh | 9 - .../magic_cookies_test_starter.sh | 62 - .../conf/malicious_data_test_master.json.in | 44 - .../conf/malicious_data_test_master_starter.sh.in | 77 - .../malicious_data_test_globals.hpp | 33 - .../malicious_data_test_msg_sender.cpp | 1597 ------- .../malicious_data_test_service.cpp | 185 - test/network_tests/CMakeLists.txt | 4391 ++++++++++++++++++++ .../application_tests/application_test.cpp | 479 +++ .../application_test_availability.cpp | 39 + .../application_test_availability_starter.sh | 10 + .../application_tests/application_test_client.cpp | 199 + .../application_test_client_availability.cpp | 203 + .../application_tests/application_test_daemon.cpp | 42 + .../application_tests/application_test_globals.hpp | 28 + .../application_tests/application_test_service.cpp | 128 + .../application_test_single_process.cpp | 47 + .../application_test_single_process.json | 14 + .../application_test_single_process_starter.sh | 23 + .../application_tests/application_test_starter.sh | 61 + .../conf/application_test.json.in | 38 + .../conf/application_test_daemon.json.in | 38 + .../application_test_no_dispatch_threads.json.in | 37 + ...ication_test_no_dispatch_threads_daemon.json.in | 37 + .../big_payload_tests/big_payload_test_client.cpp | 303 ++ .../big_payload_tests/big_payload_test_client.hpp | 52 + .../big_payload_test_client_local_start.sh | 10 + .../big_payload_test_external_client_start.sh | 10 + .../big_payload_test_external_service_start.sh | 28 + .../big_payload_test_external_starter.sh | 77 + .../big_payload_tests/big_payload_test_globals.hpp | 43 + .../big_payload_tests/big_payload_test_local.json | 56 + .../big_payload_test_local_limited.json | 44 + .../big_payload_test_local_queue_limited.json | 44 + .../big_payload_test_local_random.json | 44 + .../big_payload_test_local_starter.sh | 52 + .../big_payload_test_local_tcp_client_start.sh | 10 + .../big_payload_test_local_tcp_service_start.sh | 24 + .../big_payload_test_local_tcp_starter.sh | 74 + .../big_payload_tests/big_payload_test_service.cpp | 275 ++ .../big_payload_tests/big_payload_test_service.hpp | 51 + .../big_payload_test_service_local_start.sh | 10 + .../conf/big_payload_test_local_tcp_client.json.in | 64 + ...g_payload_test_local_tcp_client_limited.json.in | 52 + ...oad_test_local_tcp_client_queue_limited.json.in | 52 + ...ig_payload_test_local_tcp_client_random.json.in | 52 + .../big_payload_test_local_tcp_service.json.in | 68 + ..._payload_test_local_tcp_service_limited.json.in | 56 + ...ad_test_local_tcp_service_queue_limited.json.in | 56 + ...g_payload_test_local_tcp_service_random.json.in | 56 + .../conf/big_payload_test_tcp_client.json.in | 43 + ...payload_test_tcp_client_limited_general.json.in | 31 + ...d_test_tcp_client_queue_limited_general.json.in | 31 + ..._test_tcp_client_queue_limited_specific.json.in | 43 + .../big_payload_test_tcp_client_random.json.in | 32 + .../conf/big_payload_test_tcp_service.json.in | 81 + ...ayload_test_tcp_service_limited_general.json.in | 69 + ..._test_tcp_service_queue_limited_general.json.in | 87 + ...test_tcp_service_queue_limited_specific.json.in | 99 + .../big_payload_test_tcp_service_random.json.in | 70 + .../conf/big_payload_test_udp_client.json.in | 44 + .../conf/big_payload_test_udp_service.json.in | 41 + .../client_id_tests/client_id_test_globals.hpp | 34 + .../client_id_test_master_starter.sh | 80 + .../client_id_tests/client_id_test_service.cpp | 292 ++ .../client_id_test_slave_starter.sh | 50 + .../client_id_tests/client_id_test_utility.cpp | 608 +++ .../client_id_tests/client_id_test_utility.json | 35 + ...t_id_test_utility_discontinuous_masked_511.json | 36 + .../client_id_test_utility_masked_127.json | 36 + .../client_id_test_utility_masked_4095.json | 36 + .../client_id_test_utility_masked_511.json | 36 + ..._test_diff_client_ids_diff_ports_master.json.in | 70 + ...d_test_diff_client_ids_diff_ports_slave.json.in | 70 + ...ff_client_ids_partial_same_ports_master.json.in | 70 + ...iff_client_ids_partial_same_ports_slave.json.in | 70 + ..._test_diff_client_ids_same_ports_master.json.in | 70 + ...d_test_diff_client_ids_same_ports_slave.json.in | 70 + ..._test_same_client_ids_diff_ports_master.json.in | 70 + ...d_test_same_client_ids_diff_ports_slave.json.in | 70 + ..._test_same_client_ids_same_ports_master.json.in | 70 + ...d_test_same_client_ids_same_ports_slave.json.in | 70 + .../configuration-test-deprecated.json | 496 +++ .../configuration_tests/configuration-test.cpp | 832 ++++ .../configuration_tests/configuration-test.json | 492 +++ .../conf/cpu_load_test_client_master.json.in | 38 + .../conf/cpu_load_test_client_slave.json.in | 38 + .../conf/cpu_load_test_service_master.json.in | 51 + .../conf/cpu_load_test_service_slave.json.in | 51 + .../cpu_load_tests/cpu_load_measurer.cpp | 159 + .../cpu_load_tests/cpu_load_measurer.hpp | 35 + .../cpu_load_tests/cpu_load_test_client.cpp | 390 ++ .../cpu_load_tests/cpu_load_test_globals.hpp | 18 + .../cpu_load_tests/cpu_load_test_master_starter.sh | 75 + .../cpu_load_tests/cpu_load_test_service.cpp | 209 + .../cpu_load_tests/cpu_load_test_slave_starter.sh | 52 + .../conf/debounce_test_client.json.in | 52 + .../conf/debounce_test_service.json.in | 19 + .../debounce_tests/debounce_test_client.cpp | 402 ++ .../debounce_tests/debounce_test_client.hpp | 56 + .../debounce_tests/debounce_test_common.hpp | 29 + .../debounce_tests/debounce_test_master_starter.sh | 52 + .../debounce_tests/debounce_test_service.cpp | 286 ++ .../debounce_tests/debounce_test_service.hpp | 48 + .../debounce_tests/debounce_test_slave_starter.sh | 31 + .../e2e_profile_04_test_client_external.json.in | 56 + .../e2e_profile_04_test_service_external.json.in | 57 + .../conf/e2e_test_client_external.json.in | 83 + .../conf/e2e_test_service_external.json.in | 66 + .../e2e_tests/e2e_profile_04_test_client.cpp | 313 ++ .../e2e_tests/e2e_profile_04_test_client.hpp | 48 + .../e2e_tests/e2e_profile_04_test_common.hpp | 24 + .../e2e_profile_04_test_external_master_start.sh | 71 + .../e2e_profile_04_test_external_slave_start.sh | 45 + .../e2e_tests/e2e_profile_04_test_service.cpp | 324 ++ .../e2e_tests/e2e_profile_04_test_service.hpp | 48 + test/network_tests/e2e_tests/e2e_test_client.cpp | 387 ++ test/network_tests/e2e_tests/e2e_test_client.hpp | 55 + .../e2e_tests/e2e_test_external_master_start.sh | 71 + .../e2e_tests/e2e_test_external_slave_start.sh | 45 + test/network_tests/e2e_tests/e2e_test_service.cpp | 300 ++ test/network_tests/e2e_tests/e2e_test_service.hpp | 44 + .../event_tests/conf/event_test_master.json.in | 32 + .../event_tests/conf/event_test_slave_tcp.json.in | 43 + .../event_tests/conf/event_test_slave_udp.json.in | 40 + .../event_tests/event_test_client.cpp | 284 ++ .../event_tests/event_test_globals.hpp | 33 + .../event_tests/event_test_master_starter.sh | 61 + .../event_tests/event_test_service.cpp | 201 + .../event_tests/event_test_slave_starter.sh | 44 + .../header_factory_tests/header_factory_test.cpp | 119 + .../header_factory_test_client.cpp | 170 + .../header_factory_test_client.hpp | 48 + .../header_factory_test_client.json | 97 + .../header_factory_test_client_start.sh | 8 + .../header_factory_test_send_receive_starter.sh | 39 + .../header_factory_test_service.cpp | 170 + .../header_factory_test_service.hpp | 45 + .../header_factory_test_service.json | 105 + .../header_factory_test_service_start.sh | 9 + ..._test_diff_client_ids_diff_ports_master.json.in | 81 + ...t_diff_client_ids_diff_ports_master_tcp.json.in | 78 + ...t_diff_client_ids_diff_ports_master_udp.json.in | 66 + ...t_ids_diff_ports_same_service_id_master.json.in | 81 + ...nt_ids_diff_ports_same_service_id_slave.json.in | 82 + ...t_test_diff_client_ids_diff_ports_slave.json.in | 82 + ...st_diff_client_ids_diff_ports_slave_tcp.json.in | 79 + ...st_diff_client_ids_diff_ports_slave_udp.json.in | 67 + ...ff_client_ids_partial_same_ports_master.json.in | 81 + ...iff_client_ids_partial_same_ports_slave.json.in | 82 + ..._test_diff_client_ids_same_ports_master.json.in | 81 + ...t_diff_client_ids_same_ports_master_tcp.json.in | 78 + ...t_diff_client_ids_same_ports_master_udp.json.in | 66 + ...t_test_diff_client_ids_same_ports_slave.json.in | 82 + ...st_diff_client_ids_same_ports_slave_tcp.json.in | 79 + ...st_diff_client_ids_same_ports_slave_udp.json.in | 67 + ..._test_same_client_ids_diff_ports_master.json.in | 81 + ...t_test_same_client_ids_diff_ports_slave.json.in | 82 + ..._test_same_client_ids_same_ports_master.json.in | 81 + ...t_test_same_client_ids_same_ports_slave.json.in | 82 + .../initial_event_test_availability_checker.cpp | 165 + .../initial_event_test_client.cpp | 635 +++ .../initial_event_test_globals.hpp | 51 + .../initial_event_test_master_starter.sh | 143 + .../initial_event_test_service.cpp | 171 + .../initial_event_test_slave_starter.sh | 104 + .../initial_event_test_stop_service.cpp | 287 ++ .../conf/magic_cookies_test_client.json.in | 85 + .../conf/magic_cookies_test_service.json.in | 88 + .../magic_cookies_test_client.cpp | 246 ++ .../magic_cookies_test_client_start.sh | 9 + .../magic_cookies_test_service.cpp | 168 + .../magic_cookies_test_service_start.sh | 9 + .../magic_cookies_test_starter.sh | 59 + .../conf/malicious_data_test_master.json.in | 44 + .../conf/malicious_data_test_master_starter.sh.in | 73 + .../malicious_data_test_globals.hpp | 33 + .../malicious_data_test_msg_sender.cpp | 1597 +++++++ .../malicious_data_test_service.cpp | 185 + .../conf/npdu_test_client_no_npdu.json.in | 39 + .../npdu_tests/conf/npdu_test_client_npdu.json.in | 167 + .../conf/npdu_test_service_no_npdu.json.in | 87 + .../npdu_tests/conf/npdu_test_service_npdu.json.in | 168 + test/network_tests/npdu_tests/npdu_test_client.cpp | 599 +++ test/network_tests/npdu_tests/npdu_test_client.hpp | 103 + .../npdu_tests/npdu_test_client_no_npdu_start.sh | 82 + .../npdu_tests/npdu_test_client_npdu_start.sh | 75 + .../network_tests/npdu_tests/npdu_test_globals.hpp | 45 + test/network_tests/npdu_tests/npdu_test_rmd.cpp | 160 + test/network_tests/npdu_tests/npdu_test_rmd.hpp | 45 + .../network_tests/npdu_tests/npdu_test_service.cpp | 306 ++ .../network_tests/npdu_tests/npdu_test_service.hpp | 64 + .../npdu_tests/npdu_test_service_no_npdu_start.sh | 64 + .../npdu_tests/npdu_test_service_npdu_start.sh | 64 + test/network_tests/npdu_tests/npdu_test_starter.sh | 96 + .../conf/offer_test_big_sd_msg_master.json.in | 31 + .../offer_test_big_sd_msg_master_starter.sh.in | 79 + .../conf/offer_test_big_sd_msg_slave.json.in | 334 ++ .../conf/offer_test_external_master.json.in | 36 + .../conf/offer_test_external_master_starter.sh.in | 158 + .../conf/offer_test_external_slave.json.in | 36 + .../offer_tests/offer_test_big_sd_msg_client.cpp | 238 ++ .../offer_tests/offer_test_big_sd_msg_service.cpp | 172 + .../offer_test_big_sd_msg_slave_starter.sh | 45 + .../offer_tests/offer_test_client.cpp | 288 ++ .../offer_test_external_sd_msg_sender.cpp | 78 + .../offer_test_external_slave_starter.sh | 45 + .../offer_tests/offer_test_globals.hpp | 29 + .../offer_tests/offer_test_local.json | 20 + .../offer_tests/offer_test_local_starter.sh | 298 ++ .../offer_tests/offer_test_service.cpp | 171 + .../offer_tests/offer_test_service_external.cpp | 155 + .../offered_services_info_test_client.cpp | 333 ++ .../offered_services_info_test_globals.hpp | 29 + .../offered_services_info_test_local.json | 57 + .../offered_services_info_test_local_starter.sh | 58 + .../offered_services_info_test_service.cpp | 264 ++ ...rnal_local_payload_test_client_external.json.in | 53 + ...xternal_local_payload_test_client_local.json.in | 54 + .../external_local_payload_test_service.json.in | 51 + ...nal_local_payload_test_client_external_start.sh | 13 + ...l_local_payload_test_client_external_starter.sh | 121 + ...yload_test_client_local_and_external_starter.sh | 139 + ...ternal_local_payload_test_client_local_start.sh | 9 + ...rnal_local_payload_test_client_local_starter.sh | 91 + ...l_payload_test_service_client_external_start.sh | 12 + .../external_local_payload_test_service_start.sh | 9 + .../payload_tests/local_payload_test_client.json | 36 + .../local_payload_test_client_start.sh | 9 + .../local_payload_test_huge_payload_starter.sh | 43 + .../payload_tests/local_payload_test_service.json | 40 + .../local_payload_test_service_start.sh | 9 + .../payload_tests/local_payload_test_starter.sh | 69 + .../payload_tests/payload_test_client.cpp | 415 ++ .../payload_tests/payload_test_client.hpp | 71 + .../payload_tests/payload_test_service.cpp | 185 + .../payload_tests/payload_test_service.hpp | 45 + test/network_tests/payload_tests/stopwatch.cpp | 38 + test/network_tests/payload_tests/stopwatch.hpp | 58 + .../conf/pending_subscription_test_master.json.in | 55 + .../pending_subscription_test_master_starter.sh.in | 72 + .../pending_subscription_test_globals.hpp | 36 + .../pending_subscription_test_sd_msg_sender.cpp | 1735 ++++++++ .../pending_subscription_test_service.cpp | 389 ++ test/network_tests/readme.txt | 573 +++ .../restart_routing_test_autoconfig.json | 24 + .../restart_routing_test_client.cpp | 163 + .../restart_routing_test_client.hpp | 52 + .../restart_routing_test_client.json | 48 + .../restart_routing_test_client_start.sh | 9 + .../restart_routing_test_service.cpp | 133 + .../restart_routing_test_service.hpp | 44 + .../restart_routing_test_service.json | 44 + .../restart_routing_test_service_start.sh | 9 + .../restart_routing_test_starter.sh | 312 ++ ...rnal_local_routing_test_client_external.json.in | 47 + .../external_local_routing_test_service.json.in | 42 + .../conf/local_routing_test_starter.sh.bat.in | 79 + .../conf/local_routing_test_starter.sh.in | 79 + ...nal_local_routing_test_client_external_start.sh | 17 + .../external_local_routing_test_service.cpp | 185 + .../external_local_routing_test_service.hpp | 46 + .../external_local_routing_test_service_start.sh | 9 + .../external_local_routing_test_starter.sh | 121 + .../routing_tests/local_routing_test_client.cpp | 167 + .../routing_tests/local_routing_test_client.hpp | 48 + .../routing_tests/local_routing_test_client.json | 38 + .../local_routing_test_client_start.sh | 9 + .../routing_tests/local_routing_test_service.cpp | 164 + .../routing_tests/local_routing_test_service.hpp | 45 + .../routing_tests/local_routing_test_service.json | 41 + .../local_routing_test_service_start.sh | 9 + .../conf/second_address_test_master_client.json.in | 32 + .../second_address_test_master_service_udp.json.in | 40 + .../conf/second_address_test_slave_client.json.in | 32 + .../second_address_test_slave_service_udp.json.in | 40 + .../conf/second_address_test_slave_starter.sh.in | 60 + .../second_address_test_client.cpp | 353 ++ .../second_address_test_globals.hpp | 29 + .../second_address_test_master_starter.sh | 77 + .../second_address_test_service.cpp | 252 ++ ...urity_test_config_client_external_allow.json.in | 90 + ...curity_test_config_client_external_deny.json.in | 90 + ...rity_test_config_service_external_allow.json.in | 84 + ...urity_test_config_service_external_deny.json.in | 84 + .../conf/security_test_local_config.json.in | 78 + .../security_tests/security_test_client.cpp | 278 ++ .../security_tests/security_test_client.hpp | 55 + .../security_test_external_master_start.sh | 78 + .../security_test_external_slave_start.sh | 55 + .../security_tests/security_test_local_start.sh | 25 + .../security_tests/security_test_service.cpp | 217 + .../security_tests/security_test_service.hpp | 44 + test/network_tests/someip_test_globals.hpp | 43 + .../conf/someip_tp_test_master.json.in | 45 + .../conf/someip_tp_test_master_starter.sh.in | 65 + .../someip_tp_tests/someip_tp_test_globals.hpp | 40 + .../someip_tp_tests/someip_tp_test_msg_sender.cpp | 1387 +++++++ .../someip_tp_tests/someip_tp_test_service.cpp | 413 ++ ..._test_diff_client_ids_diff_ports_master.json.in | 104 + ...t_diff_client_ids_diff_ports_master_tcp.json.in | 77 + ...t_diff_client_ids_diff_ports_master_udp.json.in | 65 + ...e_test_diff_client_ids_diff_ports_slave.json.in | 104 + ...st_diff_client_ids_diff_ports_slave_tcp.json.in | 77 + ...st_diff_client_ids_diff_ports_slave_udp.json.in | 65 + .../subscribe_notify_one_test_globals.hpp | 35 + .../subscribe_notify_one_test_master_starter.sh | 79 + .../subscribe_notify_one_test_service.cpp | 497 +++ .../subscribe_notify_one_test_slave_starter.sh | 50 + ...client_ids_diff_ports_autoconfig_master.json.in | 60 + ..._diff_ports_autoconfig_master_local_tcp.json.in | 68 + ..._client_ids_diff_ports_autoconfig_slave.json.in | 60 + ...s_diff_ports_autoconfig_slave_local_tcp.json.in | 68 + ..._test_diff_client_ids_diff_ports_master.json.in | 76 + ..._client_ids_diff_ports_master_local_tcp.json.in | 83 + ...t_diff_client_ids_diff_ports_master_tcp.json.in | 73 + ...ent_ids_diff_ports_master_tcp_local_tcp.json.in | 80 + ...t_diff_client_ids_diff_ports_master_udp.json.in | 61 + ...ent_ids_diff_ports_master_udp_local_tcp.json.in | 68 + ...s_diff_ports_same_service_id_master_udp.json.in | 61 + ...ts_same_service_id_master_udp_local_tcp.json.in | 68 + ...ds_diff_ports_same_service_id_slave_udp.json.in | 61 + ...rts_same_service_id_slave_udp_local_tcp.json.in | 68 + ...y_test_diff_client_ids_diff_ports_slave.json.in | 76 + ...f_client_ids_diff_ports_slave_local_tcp.json.in | 83 + ...st_diff_client_ids_diff_ports_slave_tcp.json.in | 73 + ...ient_ids_diff_ports_slave_tcp_local_tcp.json.in | 85 + ...st_diff_client_ids_diff_ports_slave_udp.json.in | 61 + ...ient_ids_diff_ports_slave_udp_local_tcp.json.in | 68 + ...ff_client_ids_partial_same_ports_master.json.in | 76 + ...ids_partial_same_ports_master_local_tcp.json.in | 83 + ...iff_client_ids_partial_same_ports_slave.json.in | 76 + ..._ids_partial_same_ports_slave_local_tcp.json.in | 83 + ..._test_diff_client_ids_same_ports_master.json.in | 76 + ..._client_ids_same_ports_master_local_tcp.json.in | 83 + ...t_diff_client_ids_same_ports_master_tcp.json.in | 73 + ...ent_ids_same_ports_master_tcp_local_tcp.json.in | 80 + ...t_diff_client_ids_same_ports_master_udp.json.in | 61 + ...ent_ids_same_ports_master_udp_local_tcp.json.in | 68 + ...y_test_diff_client_ids_same_ports_slave.json.in | 76 + ...f_client_ids_same_ports_slave_local_tcp.json.in | 83 + ...st_diff_client_ids_same_ports_slave_tcp.json.in | 73 + ...ient_ids_same_ports_slave_tcp_local_tcp.json.in | 80 + ...st_diff_client_ids_same_ports_slave_udp.json.in | 61 + ...ient_ids_same_ports_slave_udp_local_tcp.json.in | 68 + ...y_test_one_event_two_eventgroups_master.json.in | 31 + ..._event_two_eventgroups_master_local_tcp.json.in | 38 + ...est_one_event_two_eventgroups_tcp_slave.json.in | 39 + ...ent_two_eventgroups_tcp_slave_local_tcp.json.in | 46 + ...est_one_event_two_eventgroups_udp_slave.json.in | 39 + ...ent_two_eventgroups_udp_slave_local_tcp.json.in | 46 + ..._test_same_client_ids_diff_ports_master.json.in | 76 + ..._client_ids_diff_ports_master_local_tcp.json.in | 83 + ...y_test_same_client_ids_diff_ports_slave.json.in | 76 + ...e_client_ids_diff_ports_slave_local_tcp.json.in | 83 + ..._test_same_client_ids_same_ports_master.json.in | 76 + ..._client_ids_same_ports_master_local_tcp.json.in | 83 + ...y_test_same_client_ids_same_ports_slave.json.in | 76 + ...e_client_ids_same_ports_slave_local_tcp.json.in | 83 + .../subscribe_notify_test_globals.hpp | 55 + .../subscribe_notify_test_master_starter.sh | 85 + ...otify_test_one_event_two_eventgroups_client.cpp | 395 ++ ...est_one_event_two_eventgroups_master_starter.sh | 84 + ...tify_test_one_event_two_eventgroups_service.cpp | 248 ++ ...test_one_event_two_eventgroups_slave_starter.sh | 47 + .../subscribe_notify_test_service.cpp | 514 +++ .../subscribe_notify_test_slave_starter.sh | 55 + .../conf/suspend_resume_test_client.json.in | 32 + .../conf/suspend_resume_test_service.json.in | 40 + .../suspend_resume_tests/suspend_resume_test.hpp | 22 + .../suspend_resume_test_client.cpp | 239 ++ .../suspend_resume_test_master_starter.sh | 69 + .../suspend_resume_test_service.cpp | 213 + .../suspend_resume_test_slave_starter.sh | 29 + .../conf/npdu_test_client_no_npdu.json.in | 39 - test/npdu_tests/conf/npdu_test_client_npdu.json.in | 167 - .../conf/npdu_test_service_no_npdu.json.in | 87 - .../npdu_tests/conf/npdu_test_service_npdu.json.in | 168 - test/npdu_tests/npdu_test_client.cpp | 599 --- test/npdu_tests/npdu_test_client.hpp | 103 - test/npdu_tests/npdu_test_client_no_npdu_start.sh | 82 - test/npdu_tests/npdu_test_client_npdu_start.sh | 75 - test/npdu_tests/npdu_test_globals.hpp | 45 - test/npdu_tests/npdu_test_rmd.cpp | 160 - test/npdu_tests/npdu_test_rmd.hpp | 45 - test/npdu_tests/npdu_test_service.cpp | 306 -- test/npdu_tests/npdu_test_service.hpp | 64 - test/npdu_tests/npdu_test_service_no_npdu_start.sh | 64 - test/npdu_tests/npdu_test_service_npdu_start.sh | 64 - test/npdu_tests/npdu_test_starter.sh | 100 - .../conf/offer_test_big_sd_msg_master.json.in | 31 - .../offer_test_big_sd_msg_master_starter.sh.in | 83 - .../conf/offer_test_big_sd_msg_slave.json.in | 334 -- .../conf/offer_test_external_master.json.in | 36 - .../conf/offer_test_external_master_starter.sh.in | 162 - .../conf/offer_test_external_slave.json.in | 36 - test/offer_tests/offer_test_big_sd_msg_client.cpp | 238 -- test/offer_tests/offer_test_big_sd_msg_service.cpp | 172 - .../offer_test_big_sd_msg_slave_starter.sh | 45 - test/offer_tests/offer_test_client.cpp | 288 -- .../offer_test_external_sd_msg_sender.cpp | 92 - .../offer_test_external_slave_sd_starter.sh | 38 - .../offer_test_external_slave_starter.sh | 45 - test/offer_tests/offer_test_globals.hpp | 29 - test/offer_tests/offer_test_local.json | 20 - test/offer_tests/offer_test_local_starter.sh | 298 -- test/offer_tests/offer_test_service.cpp | 171 - .../offer_test_service_availability_checker.cpp | 118 - test/offer_tests/offer_test_service_external.cpp | 155 - .../offered_services_info_test_client.cpp | 333 -- .../offered_services_info_test_globals.hpp | 29 - .../offered_services_info_test_local.json | 57 - .../offered_services_info_test_local_starter.sh | 58 - .../offered_services_info_test_service.cpp | 264 -- ...rnal_local_payload_test_client_external.json.in | 53 - ...xternal_local_payload_test_client_local.json.in | 54 - .../external_local_payload_test_service.json.in | 51 - ...nal_local_payload_test_client_external_start.sh | 13 - ...l_local_payload_test_client_external_starter.sh | 124 - ...yload_test_client_local_and_external_starter.sh | 142 - ...ternal_local_payload_test_client_local_start.sh | 9 - ...rnal_local_payload_test_client_local_starter.sh | 91 - ...l_payload_test_service_client_external_start.sh | 12 - .../external_local_payload_test_service_start.sh | 9 - test/payload_tests/local_payload_test_client.json | 36 - .../local_payload_test_client_start.sh | 9 - .../local_payload_test_huge_payload_starter.sh | 43 - test/payload_tests/local_payload_test_service.json | 40 - .../local_payload_test_service_start.sh | 9 - test/payload_tests/local_payload_test_starter.sh | 69 - test/payload_tests/payload_test_client.cpp | 415 -- test/payload_tests/payload_test_client.hpp | 71 - test/payload_tests/payload_test_service.cpp | 185 - test/payload_tests/payload_test_service.hpp | 45 - test/payload_tests/stopwatch.cpp | 38 - test/payload_tests/stopwatch.hpp | 58 - .../conf/pending_subscription_test_master.json.in | 55 - .../pending_subscription_test_master_starter.sh.in | 75 - .../pending_subscription_test_globals.hpp | 36 - .../pending_subscription_test_sd_msg_sender.cpp | 1735 -------- .../pending_subscription_test_service.cpp | 389 -- test/readme.txt | 573 --- .../restart_routing_test_autoconfig.json | 24 - .../restart_routing_test_client.cpp | 163 - .../restart_routing_test_client.hpp | 52 - .../restart_routing_test_client.json | 48 - .../restart_routing_test_client_start.sh | 9 - .../restart_routing_test_service.cpp | 133 - .../restart_routing_test_service.hpp | 44 - .../restart_routing_test_service.json | 44 - .../restart_routing_test_service_start.sh | 9 - .../restart_routing_test_starter.sh | 312 -- ...rnal_local_routing_test_client_external.json.in | 44 - .../external_local_routing_test_service.json.in | 42 - .../conf/local_routing_test_starter.sh.bat.in | 79 - .../conf/local_routing_test_starter.sh.in | 79 - ...nal_local_routing_test_client_external_start.sh | 9 - .../external_local_routing_test_service.cpp | 185 - .../external_local_routing_test_service.hpp | 46 - .../external_local_routing_test_service_start.sh | 9 - .../external_local_routing_test_starter.sh | 124 - test/routing_tests/local_routing_test_client.cpp | 167 - test/routing_tests/local_routing_test_client.hpp | 48 - test/routing_tests/local_routing_test_client.json | 38 - .../local_routing_test_client_start.sh | 9 - test/routing_tests/local_routing_test_service.cpp | 164 - test/routing_tests/local_routing_test_service.hpp | 45 - test/routing_tests/local_routing_test_service.json | 41 - .../local_routing_test_service_start.sh | 9 - .../conf/second_address_test_master_client.json.in | 32 - .../second_address_test_master_service_udp.json.in | 40 - .../conf/second_address_test_slave_client.json.in | 32 - .../second_address_test_slave_service_udp.json.in | 40 - .../conf/second_address_test_slave_starter.sh.in | 60 - .../second_address_test_client.cpp | 353 -- .../second_address_test_globals.hpp | 29 - .../second_address_test_master_starter.sh | 80 - .../second_address_test_service.cpp | 252 -- ...urity_test_config_client_external_allow.json.in | 90 - ...curity_test_config_client_external_deny.json.in | 90 - ...rity_test_config_service_external_allow.json.in | 84 - ...urity_test_config_service_external_deny.json.in | 84 - .../conf/security_test_local_config.json.in | 78 - test/security_tests/security_test_client.cpp | 278 -- test/security_tests/security_test_client.hpp | 55 - .../security_test_external_master_start.sh | 81 - .../security_test_external_slave_start.sh | 55 - test/security_tests/security_test_local_start.sh | 25 - test/security_tests/security_test_service.cpp | 217 - test/security_tests/security_test_service.hpp | 44 - test/someip_test_globals.hpp | 43 - .../conf/someip_tp_test_master.json.in | 45 - .../conf/someip_tp_test_master_starter.sh.in | 69 - test/someip_tp_tests/someip_tp_test_globals.hpp | 40 - test/someip_tp_tests/someip_tp_test_msg_sender.cpp | 1387 ------- test/someip_tp_tests/someip_tp_test_service.cpp | 413 -- ..._test_diff_client_ids_diff_ports_master.json.in | 104 - ...t_diff_client_ids_diff_ports_master_tcp.json.in | 77 - ...t_diff_client_ids_diff_ports_master_udp.json.in | 65 - ...e_test_diff_client_ids_diff_ports_slave.json.in | 104 - ...st_diff_client_ids_diff_ports_slave_tcp.json.in | 77 - ...st_diff_client_ids_diff_ports_slave_udp.json.in | 65 - .../subscribe_notify_one_test_globals.hpp | 35 - .../subscribe_notify_one_test_master_starter.sh | 82 - .../subscribe_notify_one_test_service.cpp | 497 --- .../subscribe_notify_one_test_slave_starter.sh | 50 - ...client_ids_diff_ports_autoconfig_master.json.in | 60 - ..._client_ids_diff_ports_autoconfig_slave.json.in | 60 - ..._test_diff_client_ids_diff_ports_master.json.in | 76 - ...t_diff_client_ids_diff_ports_master_tcp.json.in | 73 - ...t_diff_client_ids_diff_ports_master_udp.json.in | 61 - ...s_diff_ports_same_service_id_master_udp.json.in | 61 - ...ds_diff_ports_same_service_id_slave_udp.json.in | 61 - ...y_test_diff_client_ids_diff_ports_slave.json.in | 76 - ...st_diff_client_ids_diff_ports_slave_tcp.json.in | 73 - ...st_diff_client_ids_diff_ports_slave_udp.json.in | 61 - ...ff_client_ids_partial_same_ports_master.json.in | 76 - ...iff_client_ids_partial_same_ports_slave.json.in | 76 - ..._test_diff_client_ids_same_ports_master.json.in | 76 - ...t_diff_client_ids_same_ports_master_tcp.json.in | 73 - ...t_diff_client_ids_same_ports_master_udp.json.in | 61 - ...y_test_diff_client_ids_same_ports_slave.json.in | 76 - ...st_diff_client_ids_same_ports_slave_tcp.json.in | 73 - ...st_diff_client_ids_same_ports_slave_udp.json.in | 61 - ...y_test_one_event_two_eventgroups_master.json.in | 31 - ...est_one_event_two_eventgroups_tcp_slave.json.in | 39 - ...est_one_event_two_eventgroups_udp_slave.json.in | 39 - ..._test_same_client_ids_diff_ports_master.json.in | 76 - ...y_test_same_client_ids_diff_ports_slave.json.in | 76 - ..._test_same_client_ids_same_ports_master.json.in | 76 - ...y_test_same_client_ids_same_ports_slave.json.in | 76 - .../subscribe_notify_test_globals.hpp | 55 - .../subscribe_notify_test_master_starter.sh | 88 - ...otify_test_one_event_two_eventgroups_client.cpp | 395 -- ...est_one_event_two_eventgroups_master_starter.sh | 86 - ...tify_test_one_event_two_eventgroups_service.cpp | 248 -- ...test_one_event_two_eventgroups_slave_starter.sh | 45 - .../subscribe_notify_test_service.cpp | 512 --- .../subscribe_notify_test_slave_starter.sh | 55 - .../conf/suspend_resume_test_client.json.in | 32 - .../conf/suspend_resume_test_service.json.in | 40 - test/suspend_resume_tests/suspend_resume_test.hpp | 22 - .../suspend_resume_test_client.cpp | 239 -- .../suspend_resume_test_master_starter.sh | 72 - .../suspend_resume_test_service.cpp | 213 - .../suspend_resume_test_slave_starter.sh | 29 - test/unit_tests/CMakeLists.txt | 29 + test/unit_tests/main.cpp | 16 + .../security_tests/ut_check_credentials.cpp | 122 + .../ut_check_routing_credentials.cpp | 85 + .../ut_get_client_to_sec_client_mapping.cpp | 62 + test/unit_tests/security_tests/ut_get_clients.cpp | 56 + .../ut_get_sec_client_to_clients_mapping.cpp | 61 + .../security_tests/ut_is_client_allowed.cpp | 149 + .../security_tests/ut_is_offer_allowed.cpp | 153 + .../security_tests/ut_is_policy_update_allowed.cpp | 221 + .../unit_tests/security_tests/ut_load_policies.cpp | 100 + .../ut_load_security_update_whitelist.cpp | 218 + .../ut_remove_client_to_sec_client_mapping.cpp | 41 + .../security_tests/ut_remove_security_policy.cpp | 61 + tools/CMakeLists.txt | 2 - vsomeip.pc.in | 1 - vsomeip3.pc.in | 1 - 1260 files changed, 85394 insertions(+), 118515 deletions(-) create mode 100644 Android.mk create mode 100644 documentation/vsomeipProtocol create mode 100644 implementation/configuration/include/application_configuration.hpp create mode 100644 implementation/configuration/include/routing.hpp delete mode 100644 implementation/endpoints/include/local_client_endpoint_impl.hpp delete mode 100644 implementation/endpoints/include/local_server_endpoint_impl.hpp create mode 100644 implementation/endpoints/include/local_server_endpoint_impl_receive_op.hpp create mode 100644 implementation/endpoints/include/local_tcp_client_endpoint_impl.hpp create mode 100644 implementation/endpoints/include/local_tcp_server_endpoint_impl.hpp create mode 100644 implementation/endpoints/include/local_uds_client_endpoint_impl.hpp create mode 100644 implementation/endpoints/include/local_uds_server_endpoint_impl.hpp create mode 100644 implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp delete mode 100644 implementation/endpoints/src/local_client_endpoint_impl.cpp delete mode 100644 implementation/endpoints/src/local_server_endpoint_impl.cpp create mode 100644 implementation/endpoints/src/local_tcp_client_endpoint_impl.cpp create mode 100644 implementation/endpoints/src/local_tcp_server_endpoint_impl.cpp create mode 100644 implementation/endpoints/src/local_uds_client_endpoint_impl.cpp create mode 100644 implementation/endpoints/src/local_uds_server_endpoint_impl.cpp delete mode 100644 implementation/helper/1.55/boost/asio/basic_datagram_socket_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/basic_socket_acceptor_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/basic_stream_socket_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/datagram_socket_service_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext_local.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp delete mode 100644 implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp delete mode 100644 implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext.ipp delete mode 100644 implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext_local.ipp delete mode 100644 implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext_local.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext_local.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/reactor_op_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/reactor_op_ext_local.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/socket_ops_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/detail/socket_ops_ext_local.hpp delete mode 100644 implementation/helper/1.55/boost/asio/ip/udp_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/local/stream_protocol_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/socket_acceptor_service_ext.hpp delete mode 100644 implementation/helper/1.55/boost/asio/stream_socket_service_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/basic_datagram_socket_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/basic_socket_acceptor_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/basic_socket_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/basic_socket_ext_local.hpp delete mode 100644 implementation/helper/1.66/boost/asio/basic_stream_socket_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext_local.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp delete mode 100644 implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp delete mode 100644 implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext.ipp delete mode 100644 implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext_local.ipp delete mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext_local.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext_local.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/reactor_op_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/reactor_op_ext_local.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/socket_ops_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/detail/socket_ops_ext_local.hpp delete mode 100644 implementation/helper/1.66/boost/asio/ip/udp_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/local/stream_protocol_ext.hpp delete mode 100644 implementation/helper/1.66/boost/asio/stream_socket_service_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/basic_datagram_socket_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/basic_socket_acceptor_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/basic_socket_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/basic_socket_ext_local.hpp delete mode 100644 implementation/helper/1.70/boost/asio/basic_stream_socket_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext_local.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp delete mode 100644 implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp delete mode 100644 implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext.ipp delete mode 100644 implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext_local.ipp delete mode 100644 implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext_local.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext_local.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/reactor_op_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/reactor_op_ext_local.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/socket_ops_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/detail/socket_ops_ext_local.hpp delete mode 100644 implementation/helper/1.70/boost/asio/ip/udp_ext.hpp delete mode 100644 implementation/helper/1.70/boost/asio/local/stream_protocol_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/basic_datagram_socket_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/basic_socket_acceptor_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/basic_socket_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/basic_socket_ext_local.hpp delete mode 100644 implementation/helper/1.74/boost/asio/basic_stream_socket_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext_local.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp delete mode 100644 implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp delete mode 100644 implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext.ipp delete mode 100644 implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext_local.ipp delete mode 100644 implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext_local.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext_local.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/reactor_op_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/reactor_op_ext_local.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/socket_ops_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/detail/socket_ops_ext_local.hpp delete mode 100644 implementation/helper/1.74/boost/asio/ip/udp_ext.hpp delete mode 100644 implementation/helper/1.74/boost/asio/local/stream_protocol_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/basic_datagram_socket_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/basic_socket_acceptor_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/basic_socket_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/basic_socket_ext_local.hpp delete mode 100644 implementation/helper/1.76/boost/asio/basic_stream_socket_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext_local.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp delete mode 100644 implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp delete mode 100644 implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext.ipp delete mode 100644 implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext_local.ipp delete mode 100644 implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext_local.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext_local.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/reactor_op_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/reactor_op_ext_local.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/socket_ops_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/detail/socket_ops_ext_local.hpp delete mode 100644 implementation/helper/1.76/boost/asio/ip/udp_ext.hpp delete mode 100644 implementation/helper/1.76/boost/asio/local/stream_protocol_ext.hpp create mode 100644 implementation/helper/boost/asio/basic_datagram_socket_ext.hpp create mode 100644 implementation/helper/boost/asio/basic_socket_acceptor_ext.hpp create mode 100644 implementation/helper/boost/asio/basic_stream_socket_ext.hpp create mode 100644 implementation/helper/boost/asio/datagram_socket_service_ext.hpp create mode 100644 implementation/helper/boost/asio/detail/handler_type_requirements_ext.hpp create mode 100644 implementation/helper/boost/asio/detail/handler_type_requirements_ext_local.hpp create mode 100644 implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp create mode 100644 implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp create mode 100644 implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp create mode 100644 implementation/helper/boost/asio/detail/impl/socket_ops_ext_local.ipp create mode 100644 implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext.hpp create mode 100644 implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp create mode 100644 implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp create mode 100644 implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp create mode 100644 implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp create mode 100644 implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp create mode 100644 implementation/helper/boost/asio/detail/reactive_socket_service_base_ext.hpp create mode 100644 implementation/helper/boost/asio/detail/reactive_socket_service_base_ext_local.hpp create mode 100644 implementation/helper/boost/asio/detail/reactive_socket_service_ext.hpp create mode 100644 implementation/helper/boost/asio/detail/reactive_socket_service_ext_local.hpp create mode 100644 implementation/helper/boost/asio/detail/reactor_op_ext.hpp create mode 100644 implementation/helper/boost/asio/detail/reactor_op_ext_local.hpp create mode 100644 implementation/helper/boost/asio/detail/socket_ops_ext.hpp create mode 100644 implementation/helper/boost/asio/detail/socket_ops_ext_local.hpp create mode 100644 implementation/helper/boost/asio/ip/udp_ext.hpp create mode 100644 implementation/helper/boost/asio/local/stream_protocol_ext.hpp create mode 100644 implementation/helper/boost/asio/socket_acceptor_service_ext.hpp create mode 100644 implementation/helper/boost/asio/stream_socket_service_ext.hpp create mode 100644 implementation/protocol/include/assign_client_ack_command.hpp create mode 100644 implementation/protocol/include/assign_client_command.hpp create mode 100644 implementation/protocol/include/command.hpp create mode 100644 implementation/protocol/include/deregister_application_command.hpp create mode 100644 implementation/protocol/include/distribute_security_policies_command.hpp create mode 100644 implementation/protocol/include/dummy_command.hpp create mode 100644 implementation/protocol/include/expire_command.hpp create mode 100644 implementation/protocol/include/multiple_services_command_base.hpp create mode 100644 implementation/protocol/include/offer_service_command.hpp create mode 100644 implementation/protocol/include/offered_services_request_command.hpp create mode 100644 implementation/protocol/include/offered_services_response_command.hpp create mode 100644 implementation/protocol/include/ping_command.hpp create mode 100644 implementation/protocol/include/pong_command.hpp create mode 100644 implementation/protocol/include/protocol.hpp create mode 100644 implementation/protocol/include/register_application_command.hpp create mode 100644 implementation/protocol/include/register_event.hpp create mode 100644 implementation/protocol/include/register_events_command.hpp create mode 100644 implementation/protocol/include/registered_ack_command.hpp create mode 100644 implementation/protocol/include/release_service_command.hpp create mode 100644 implementation/protocol/include/remove_security_policy_command.hpp create mode 100644 implementation/protocol/include/remove_security_policy_response_command.hpp create mode 100644 implementation/protocol/include/request_service_command.hpp create mode 100644 implementation/protocol/include/resend_provided_events_command.hpp create mode 100644 implementation/protocol/include/routing_info_command.hpp create mode 100644 implementation/protocol/include/routing_info_entry.hpp create mode 100644 implementation/protocol/include/security_policy_response_command_base.hpp create mode 100644 implementation/protocol/include/send_command.hpp create mode 100644 implementation/protocol/include/service_command_base.hpp create mode 100644 implementation/protocol/include/simple_command.hpp create mode 100644 implementation/protocol/include/stop_offer_service_command.hpp create mode 100644 implementation/protocol/include/subscribe_ack_command.hpp create mode 100644 implementation/protocol/include/subscribe_ack_command_base.hpp create mode 100644 implementation/protocol/include/subscribe_command.hpp create mode 100644 implementation/protocol/include/subscribe_command_base.hpp create mode 100644 implementation/protocol/include/subscribe_nack_command.hpp create mode 100644 implementation/protocol/include/suspend_command.hpp create mode 100644 implementation/protocol/include/unregister_event_command.hpp create mode 100644 implementation/protocol/include/unsubscribe_ack_command.hpp create mode 100644 implementation/protocol/include/unsubscribe_command.hpp create mode 100644 implementation/protocol/include/update_security_credentials_command.hpp create mode 100644 implementation/protocol/include/update_security_policy_command.hpp create mode 100644 implementation/protocol/include/update_security_policy_response_command.hpp create mode 100644 implementation/protocol/src/assign_client_ack_command.cpp create mode 100644 implementation/protocol/src/assign_client_command.cpp create mode 100644 implementation/protocol/src/command.cpp create mode 100644 implementation/protocol/src/deregister_application_command.cpp create mode 100644 implementation/protocol/src/distribute_security_policies_command.cpp create mode 100644 implementation/protocol/src/dummy_command.cpp create mode 100644 implementation/protocol/src/expire_command.cpp create mode 100644 implementation/protocol/src/multiple_services_command_base.cpp create mode 100644 implementation/protocol/src/offer_service_command.cpp create mode 100644 implementation/protocol/src/offered_services_request_command.cpp create mode 100644 implementation/protocol/src/offered_services_response_command.cpp create mode 100644 implementation/protocol/src/ping_command.cpp create mode 100644 implementation/protocol/src/pong_command.cpp create mode 100644 implementation/protocol/src/register_application_command.cpp create mode 100644 implementation/protocol/src/register_event.cpp create mode 100644 implementation/protocol/src/register_events_command.cpp create mode 100644 implementation/protocol/src/registered_ack_command.cpp create mode 100644 implementation/protocol/src/release_service_command.cpp create mode 100644 implementation/protocol/src/remove_security_policy_command.cpp create mode 100644 implementation/protocol/src/remove_security_policy_response_command.cpp create mode 100644 implementation/protocol/src/request_service_command.cpp create mode 100644 implementation/protocol/src/resend_provided_events_command.cpp create mode 100644 implementation/protocol/src/routing_info_command.cpp create mode 100644 implementation/protocol/src/routing_info_entry.cpp create mode 100644 implementation/protocol/src/security_policy_response_command_base.cpp create mode 100644 implementation/protocol/src/send_command.cpp create mode 100644 implementation/protocol/src/service_command_base.cpp create mode 100644 implementation/protocol/src/simple_command.cpp create mode 100644 implementation/protocol/src/stop_offer_service_command.cpp create mode 100644 implementation/protocol/src/subscribe_ack_command.cpp create mode 100644 implementation/protocol/src/subscribe_ack_command_base.cpp create mode 100644 implementation/protocol/src/subscribe_command.cpp create mode 100644 implementation/protocol/src/subscribe_command_base.cpp create mode 100644 implementation/protocol/src/subscribe_nack_command.cpp create mode 100644 implementation/protocol/src/suspend_command.cpp create mode 100644 implementation/protocol/src/unregister_event_command.cpp create mode 100644 implementation/protocol/src/unsubscribe_ack_command.cpp create mode 100644 implementation/protocol/src/unsubscribe_command.cpp create mode 100644 implementation/protocol/src/update_security_credentials_command.cpp create mode 100644 implementation/protocol/src/update_security_policy_command.cpp create mode 100644 implementation/protocol/src/update_security_policy_response_command.cpp create mode 100644 implementation/routing/include/routing_manager_client.hpp delete mode 100644 implementation/routing/include/routing_manager_proxy.hpp create mode 100644 implementation/routing/src/routing_manager_client.cpp delete mode 100644 implementation/routing/src/routing_manager_proxy.cpp delete mode 100644 implementation/security/include/security_impl.hpp delete mode 100644 implementation/security/src/security_impl.cpp mode change 100755 => 100644 implementation/service_discovery/include/deserializer.hpp mode change 100755 => 100644 implementation/service_discovery/include/entry_impl.hpp mode change 100755 => 100644 implementation/service_discovery/include/eventgroupentry_impl.hpp mode change 100755 => 100644 implementation/service_discovery/include/load_balancing_option_impl.hpp mode change 100755 => 100644 implementation/service_discovery/include/message_element_impl.hpp mode change 100755 => 100644 implementation/service_discovery/include/message_impl.hpp mode change 100755 => 100644 implementation/service_discovery/include/protection_option_impl.hpp mode change 100755 => 100644 implementation/service_discovery/src/configuration_option_impl.cpp mode change 100755 => 100644 implementation/service_discovery/src/entry_impl.cpp mode change 100755 => 100644 implementation/service_discovery/src/eventgroupentry_impl.cpp mode change 100755 => 100644 implementation/service_discovery/src/ipv6_option_impl.cpp mode change 100755 => 100644 implementation/service_discovery/src/load_balancing_option_impl.cpp mode change 100755 => 100644 implementation/service_discovery/src/message_element_impl.cpp mode change 100755 => 100644 implementation/service_discovery/src/message_impl.cpp mode change 100755 => 100644 implementation/service_discovery/src/option_impl.cpp mode change 100755 => 100644 implementation/service_discovery/src/protection_option_impl.cpp mode change 100755 => 100644 implementation/service_discovery/src/selective_option_impl.cpp mode change 100755 => 100644 implementation/service_discovery/src/serviceentry_impl.cpp create mode 100644 implementation/utility/src/wrappers.cpp create mode 100644 interface/vsomeip/deprecated.hpp create mode 100644 interface/vsomeip/structured_types.hpp create mode 100644 interface/vsomeip/vsomeip_sec.h create mode 100644 libvsomeip.yaml delete mode 100644 test/application_tests/application_test.cpp delete mode 100644 test/application_tests/application_test_availability.cpp delete mode 100755 test/application_tests/application_test_availability_starter.sh delete mode 100644 test/application_tests/application_test_client.cpp delete mode 100644 test/application_tests/application_test_client_availability.cpp delete mode 100644 test/application_tests/application_test_daemon.cpp delete mode 100644 test/application_tests/application_test_globals.hpp delete mode 100644 test/application_tests/application_test_service.cpp delete mode 100644 test/application_tests/application_test_single_process.cpp delete mode 100644 test/application_tests/application_test_single_process.json delete mode 100755 test/application_tests/application_test_single_process_starter.sh delete mode 100755 test/application_tests/application_test_starter.sh delete mode 100644 test/application_tests/conf/application_test.json.in delete mode 100644 test/application_tests/conf/application_test_daemon.json.in delete mode 100644 test/application_tests/conf/application_test_no_dispatch_threads.json.in delete mode 100644 test/application_tests/conf/application_test_no_dispatch_threads_daemon.json.in create mode 100644 test/benchmark_tests/CMakeLists.txt create mode 100644 test/benchmark_tests/main.cpp create mode 100644 test/benchmark_tests/security_tests/bm_check_credentials.cpp create mode 100644 test/benchmark_tests/security_tests/bm_check_routing_credentials.cpp create mode 100644 test/benchmark_tests/security_tests/bm_get_client_to_sec_client_mapping.cpp create mode 100644 test/benchmark_tests/security_tests/bm_get_clients.cpp create mode 100644 test/benchmark_tests/security_tests/bm_get_sec_client_to_clients_mapping.cpp create mode 100644 test/benchmark_tests/security_tests/bm_is_client_allowed.cpp create mode 100644 test/benchmark_tests/security_tests/bm_is_offer_allowed.cpp create mode 100644 test/benchmark_tests/security_tests/bm_is_policy_update_allowed.cpp create mode 100644 test/benchmark_tests/security_tests/bm_load_policies.cpp create mode 100644 test/benchmark_tests/security_tests/bm_load_security_update_whitelist.cpp create mode 100644 test/benchmark_tests/security_tests/bm_remove_client_to_sec_client_mapping.cpp create mode 100644 test/benchmark_tests/security_tests/bm_remove_security_policy.cpp delete mode 100644 test/big_payload_tests/big_payload_test_client.cpp delete mode 100644 test/big_payload_tests/big_payload_test_client.hpp delete mode 100755 test/big_payload_tests/big_payload_test_client_local_start.sh delete mode 100755 test/big_payload_tests/big_payload_test_client_start.sh delete mode 100755 test/big_payload_tests/big_payload_test_external_starter.sh delete mode 100644 test/big_payload_tests/big_payload_test_globals.hpp delete mode 100644 test/big_payload_tests/big_payload_test_local.json delete mode 100644 test/big_payload_tests/big_payload_test_local_limited.json delete mode 100644 test/big_payload_tests/big_payload_test_local_queue_limited.json delete mode 100644 test/big_payload_tests/big_payload_test_local_random.json delete mode 100755 test/big_payload_tests/big_payload_test_local_starter.sh delete mode 100644 test/big_payload_tests/big_payload_test_service.cpp delete mode 100644 test/big_payload_tests/big_payload_test_service.hpp delete mode 100755 test/big_payload_tests/big_payload_test_service_external_start.sh delete mode 100755 test/big_payload_tests/big_payload_test_service_local_start.sh delete mode 100644 test/big_payload_tests/conf/big_payload_test_tcp_client.json.in delete mode 100644 test/big_payload_tests/conf/big_payload_test_tcp_client_limited_general.json.in delete mode 100644 test/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_general.json.in delete mode 100644 test/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_specific.json.in delete mode 100644 test/big_payload_tests/conf/big_payload_test_tcp_client_random.json.in delete mode 100644 test/big_payload_tests/conf/big_payload_test_tcp_service.json.in delete mode 100644 test/big_payload_tests/conf/big_payload_test_tcp_service_limited_general.json.in delete mode 100644 test/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_general.json.in delete mode 100644 test/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_specific.json.in delete mode 100644 test/big_payload_tests/conf/big_payload_test_tcp_service_random.json.in delete mode 100644 test/big_payload_tests/conf/big_payload_test_udp_client.json.in delete mode 100644 test/big_payload_tests/conf/big_payload_test_udp_service.json.in delete mode 100644 test/client_id_tests/client_id_test_globals.hpp delete mode 100755 test/client_id_tests/client_id_test_master_starter.sh delete mode 100644 test/client_id_tests/client_id_test_service.cpp delete mode 100755 test/client_id_tests/client_id_test_slave_starter.sh delete mode 100644 test/client_id_tests/client_id_test_utility.cpp delete mode 100644 test/client_id_tests/client_id_test_utility.json delete mode 100644 test/client_id_tests/client_id_test_utility_discontinuous_masked_511.json delete mode 100644 test/client_id_tests/client_id_test_utility_masked_127.json delete mode 100644 test/client_id_tests/client_id_test_utility_masked_4095.json delete mode 100644 test/client_id_tests/client_id_test_utility_masked_511.json delete mode 100644 test/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_master.json.in delete mode 100644 test/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_slave.json.in delete mode 100644 test/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_master.json.in delete mode 100644 test/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_slave.json.in delete mode 100644 test/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_master.json.in delete mode 100644 test/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_slave.json.in delete mode 100644 test/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_master.json.in delete mode 100644 test/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_slave.json.in delete mode 100644 test/client_id_tests/conf/client_id_test_same_client_ids_same_ports_master.json.in delete mode 100644 test/client_id_tests/conf/client_id_test_same_client_ids_same_ports_slave.json.in create mode 100644 test/common/examples_policies/vsomeip/0_0/vsomeip_security.json create mode 100644 test/common/examples_policies/vsomeip/4002200_4002200/vsomeip_security.json create mode 100644 test/common/examples_policies/vsomeip/4002201_4002201/vsomeip_security.json create mode 100644 test/common/examples_policies/vsomeip/4002205_4002205/vsomeip_security.json create mode 100644 test/common/examples_policies/vsomeip/4003013_4003011/vsomeip_security.json create mode 100644 test/common/examples_policies/vsomeip/4003014_4003014/vsomeip_security.json create mode 100644 test/common/examples_policies/vsomeip/4003015_4003015/vsomeip_security.json create mode 100644 test/common/examples_policies/vsomeip/4003016_4003016/vsomeip_security.json create mode 100644 test/common/examples_policies/vsomeip/vsomeip_policy_extensions.json create mode 100644 test/common/examples_policies/vsomeip/vsomeip_security.json create mode 100644 test/common/utility.cpp create mode 100644 test/common/utility.hpp delete mode 100644 test/configuration_tests/configuration-test-deprecated.json delete mode 100644 test/configuration_tests/configuration-test.cpp delete mode 100644 test/configuration_tests/configuration-test.json delete mode 100644 test/cpu_load_tests/conf/cpu_load_test_client_master.json.in delete mode 100644 test/cpu_load_tests/conf/cpu_load_test_client_slave.json.in delete mode 100644 test/cpu_load_tests/conf/cpu_load_test_service_master.json.in delete mode 100644 test/cpu_load_tests/conf/cpu_load_test_service_slave.json.in delete mode 100644 test/cpu_load_tests/cpu_load_measurer.cpp delete mode 100644 test/cpu_load_tests/cpu_load_measurer.hpp delete mode 100644 test/cpu_load_tests/cpu_load_test_client.cpp delete mode 100644 test/cpu_load_tests/cpu_load_test_globals.hpp delete mode 100755 test/cpu_load_tests/cpu_load_test_master_starter.sh delete mode 100644 test/cpu_load_tests/cpu_load_test_service.cpp delete mode 100755 test/cpu_load_tests/cpu_load_test_slave_starter.sh delete mode 100644 test/debounce_tests/debounce_test_client.json delete mode 100644 test/debounce_tests/debounce_test_service.json delete mode 100644 test/e2e_tests/conf/e2e_profile_04_test_client_external.json.in delete mode 100644 test/e2e_tests/conf/e2e_profile_04_test_service_external.json.in delete mode 100644 test/e2e_tests/conf/e2e_test_client_external.json.in delete mode 100644 test/e2e_tests/conf/e2e_test_service_external.json.in delete mode 100644 test/e2e_tests/e2e_profile_04_test_client.cpp delete mode 100644 test/e2e_tests/e2e_profile_04_test_client.hpp delete mode 100644 test/e2e_tests/e2e_profile_04_test_common.hpp delete mode 100755 test/e2e_tests/e2e_profile_04_test_external_master_start.sh delete mode 100755 test/e2e_tests/e2e_profile_04_test_external_slave_start.sh delete mode 100644 test/e2e_tests/e2e_profile_04_test_service.cpp delete mode 100644 test/e2e_tests/e2e_profile_04_test_service.hpp delete mode 100644 test/e2e_tests/e2e_test_client.cpp delete mode 100644 test/e2e_tests/e2e_test_client.hpp delete mode 100755 test/e2e_tests/e2e_test_external_master_start.sh delete mode 100755 test/e2e_tests/e2e_test_external_slave_start.sh delete mode 100644 test/e2e_tests/e2e_test_service.cpp delete mode 100644 test/e2e_tests/e2e_test_service.hpp delete mode 100644 test/event_tests/conf/event_test_master.json.in delete mode 100644 test/event_tests/conf/event_test_slave_tcp.json.in delete mode 100644 test/event_tests/conf/event_test_slave_udp.json.in delete mode 100644 test/event_tests/event_test_client.cpp delete mode 100644 test/event_tests/event_test_globals.hpp delete mode 100755 test/event_tests/event_test_master_starter.sh delete mode 100644 test/event_tests/event_test_service.cpp delete mode 100755 test/event_tests/event_test_slave_starter.sh delete mode 100644 test/header_factory_tests/header_factory_test.cpp delete mode 100644 test/header_factory_tests/header_factory_test_client.cpp delete mode 100644 test/header_factory_tests/header_factory_test_client.hpp delete mode 100644 test/header_factory_tests/header_factory_test_client.json delete mode 100755 test/header_factory_tests/header_factory_test_client_start.sh delete mode 100755 test/header_factory_tests/header_factory_test_send_receive_starter.sh delete mode 100644 test/header_factory_tests/header_factory_test_service.cpp delete mode 100644 test/header_factory_tests/header_factory_test_service.hpp delete mode 100644 test/header_factory_tests/header_factory_test_service.json delete mode 100755 test/header_factory_tests/header_factory_test_service_start.sh delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_udp.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_udp.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_master.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_slave.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_udp.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_udp.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_master.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_slave.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_master.json.in delete mode 100644 test/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_slave.json.in delete mode 100644 test/initial_event_tests/initial_event_test_availability_checker.cpp delete mode 100644 test/initial_event_tests/initial_event_test_client.cpp delete mode 100644 test/initial_event_tests/initial_event_test_globals.hpp delete mode 100755 test/initial_event_tests/initial_event_test_master_starter.sh delete mode 100644 test/initial_event_tests/initial_event_test_service.cpp delete mode 100755 test/initial_event_tests/initial_event_test_slave_starter.sh delete mode 100644 test/initial_event_tests/initial_event_test_stop_service.cpp create mode 100644 test/internal_routing_disabled_acceptance_test/CMakeLists.txt create mode 100644 test/internal_routing_disabled_acceptance_test/applet.cpp create mode 100644 test/internal_routing_disabled_acceptance_test/applet.hpp create mode 100644 test/internal_routing_disabled_acceptance_test/client.cpp create mode 100644 test/internal_routing_disabled_acceptance_test/client.hpp create mode 100644 test/internal_routing_disabled_acceptance_test/config.hpp create mode 100644 test/internal_routing_disabled_acceptance_test/main.cpp create mode 100644 test/internal_routing_disabled_acceptance_test/server.cpp create mode 100644 test/internal_routing_disabled_acceptance_test/server.hpp create mode 100644 test/internal_routing_disabled_acceptance_test/vsomeip.json delete mode 100644 test/magic_cookies_tests/conf/magic_cookies_test_client.json.in delete mode 100644 test/magic_cookies_tests/conf/magic_cookies_test_service.json.in delete mode 100644 test/magic_cookies_tests/magic_cookies_test_client.cpp delete mode 100755 test/magic_cookies_tests/magic_cookies_test_client_start.sh delete mode 100644 test/magic_cookies_tests/magic_cookies_test_service.cpp delete mode 100755 test/magic_cookies_tests/magic_cookies_test_service_start.sh delete mode 100755 test/magic_cookies_tests/magic_cookies_test_starter.sh delete mode 100644 test/malicious_data_tests/conf/malicious_data_test_master.json.in delete mode 100755 test/malicious_data_tests/conf/malicious_data_test_master_starter.sh.in delete mode 100644 test/malicious_data_tests/malicious_data_test_globals.hpp delete mode 100644 test/malicious_data_tests/malicious_data_test_msg_sender.cpp delete mode 100644 test/malicious_data_tests/malicious_data_test_service.cpp create mode 100644 test/network_tests/CMakeLists.txt create mode 100644 test/network_tests/application_tests/application_test.cpp create mode 100644 test/network_tests/application_tests/application_test_availability.cpp create mode 100755 test/network_tests/application_tests/application_test_availability_starter.sh create mode 100644 test/network_tests/application_tests/application_test_client.cpp create mode 100644 test/network_tests/application_tests/application_test_client_availability.cpp create mode 100644 test/network_tests/application_tests/application_test_daemon.cpp create mode 100644 test/network_tests/application_tests/application_test_globals.hpp create mode 100644 test/network_tests/application_tests/application_test_service.cpp create mode 100644 test/network_tests/application_tests/application_test_single_process.cpp create mode 100644 test/network_tests/application_tests/application_test_single_process.json create mode 100755 test/network_tests/application_tests/application_test_single_process_starter.sh create mode 100755 test/network_tests/application_tests/application_test_starter.sh create mode 100644 test/network_tests/application_tests/conf/application_test.json.in create mode 100644 test/network_tests/application_tests/conf/application_test_daemon.json.in create mode 100644 test/network_tests/application_tests/conf/application_test_no_dispatch_threads.json.in create mode 100644 test/network_tests/application_tests/conf/application_test_no_dispatch_threads_daemon.json.in create mode 100644 test/network_tests/big_payload_tests/big_payload_test_client.cpp create mode 100644 test/network_tests/big_payload_tests/big_payload_test_client.hpp create mode 100755 test/network_tests/big_payload_tests/big_payload_test_client_local_start.sh create mode 100755 test/network_tests/big_payload_tests/big_payload_test_external_client_start.sh create mode 100755 test/network_tests/big_payload_tests/big_payload_test_external_service_start.sh create mode 100755 test/network_tests/big_payload_tests/big_payload_test_external_starter.sh create mode 100644 test/network_tests/big_payload_tests/big_payload_test_globals.hpp create mode 100644 test/network_tests/big_payload_tests/big_payload_test_local.json create mode 100644 test/network_tests/big_payload_tests/big_payload_test_local_limited.json create mode 100644 test/network_tests/big_payload_tests/big_payload_test_local_queue_limited.json create mode 100644 test/network_tests/big_payload_tests/big_payload_test_local_random.json create mode 100755 test/network_tests/big_payload_tests/big_payload_test_local_starter.sh create mode 100755 test/network_tests/big_payload_tests/big_payload_test_local_tcp_client_start.sh create mode 100755 test/network_tests/big_payload_tests/big_payload_test_local_tcp_service_start.sh create mode 100755 test/network_tests/big_payload_tests/big_payload_test_local_tcp_starter.sh create mode 100644 test/network_tests/big_payload_tests/big_payload_test_service.cpp create mode 100644 test/network_tests/big_payload_tests/big_payload_test_service.hpp create mode 100755 test/network_tests/big_payload_tests/big_payload_test_service_local_start.sh create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_limited.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_queue_limited.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_random.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_limited.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_queue_limited.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_random.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_limited_general.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_general.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_specific.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_random.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_limited_general.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_general.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_specific.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_random.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_udp_client.json.in create mode 100644 test/network_tests/big_payload_tests/conf/big_payload_test_udp_service.json.in create mode 100644 test/network_tests/client_id_tests/client_id_test_globals.hpp create mode 100755 test/network_tests/client_id_tests/client_id_test_master_starter.sh create mode 100644 test/network_tests/client_id_tests/client_id_test_service.cpp create mode 100755 test/network_tests/client_id_tests/client_id_test_slave_starter.sh create mode 100644 test/network_tests/client_id_tests/client_id_test_utility.cpp create mode 100644 test/network_tests/client_id_tests/client_id_test_utility.json create mode 100644 test/network_tests/client_id_tests/client_id_test_utility_discontinuous_masked_511.json create mode 100644 test/network_tests/client_id_tests/client_id_test_utility_masked_127.json create mode 100644 test/network_tests/client_id_tests/client_id_test_utility_masked_4095.json create mode 100644 test/network_tests/client_id_tests/client_id_test_utility_masked_511.json create mode 100644 test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_master.json.in create mode 100644 test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_slave.json.in create mode 100644 test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_master.json.in create mode 100644 test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_slave.json.in create mode 100644 test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_master.json.in create mode 100644 test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_slave.json.in create mode 100644 test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_master.json.in create mode 100644 test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_slave.json.in create mode 100644 test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_same_ports_master.json.in create mode 100644 test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_same_ports_slave.json.in create mode 100644 test/network_tests/configuration_tests/configuration-test-deprecated.json create mode 100644 test/network_tests/configuration_tests/configuration-test.cpp create mode 100644 test/network_tests/configuration_tests/configuration-test.json create mode 100644 test/network_tests/cpu_load_tests/conf/cpu_load_test_client_master.json.in create mode 100644 test/network_tests/cpu_load_tests/conf/cpu_load_test_client_slave.json.in create mode 100644 test/network_tests/cpu_load_tests/conf/cpu_load_test_service_master.json.in create mode 100644 test/network_tests/cpu_load_tests/conf/cpu_load_test_service_slave.json.in create mode 100644 test/network_tests/cpu_load_tests/cpu_load_measurer.cpp create mode 100644 test/network_tests/cpu_load_tests/cpu_load_measurer.hpp create mode 100644 test/network_tests/cpu_load_tests/cpu_load_test_client.cpp create mode 100644 test/network_tests/cpu_load_tests/cpu_load_test_globals.hpp create mode 100755 test/network_tests/cpu_load_tests/cpu_load_test_master_starter.sh create mode 100644 test/network_tests/cpu_load_tests/cpu_load_test_service.cpp create mode 100755 test/network_tests/cpu_load_tests/cpu_load_test_slave_starter.sh create mode 100644 test/network_tests/debounce_tests/conf/debounce_test_client.json.in create mode 100644 test/network_tests/debounce_tests/conf/debounce_test_service.json.in create mode 100644 test/network_tests/debounce_tests/debounce_test_client.cpp create mode 100644 test/network_tests/debounce_tests/debounce_test_client.hpp create mode 100644 test/network_tests/debounce_tests/debounce_test_common.hpp create mode 100755 test/network_tests/debounce_tests/debounce_test_master_starter.sh create mode 100644 test/network_tests/debounce_tests/debounce_test_service.cpp create mode 100644 test/network_tests/debounce_tests/debounce_test_service.hpp create mode 100755 test/network_tests/debounce_tests/debounce_test_slave_starter.sh create mode 100644 test/network_tests/e2e_tests/conf/e2e_profile_04_test_client_external.json.in create mode 100644 test/network_tests/e2e_tests/conf/e2e_profile_04_test_service_external.json.in create mode 100644 test/network_tests/e2e_tests/conf/e2e_test_client_external.json.in create mode 100644 test/network_tests/e2e_tests/conf/e2e_test_service_external.json.in create mode 100644 test/network_tests/e2e_tests/e2e_profile_04_test_client.cpp create mode 100644 test/network_tests/e2e_tests/e2e_profile_04_test_client.hpp create mode 100644 test/network_tests/e2e_tests/e2e_profile_04_test_common.hpp create mode 100755 test/network_tests/e2e_tests/e2e_profile_04_test_external_master_start.sh create mode 100755 test/network_tests/e2e_tests/e2e_profile_04_test_external_slave_start.sh create mode 100644 test/network_tests/e2e_tests/e2e_profile_04_test_service.cpp create mode 100644 test/network_tests/e2e_tests/e2e_profile_04_test_service.hpp create mode 100644 test/network_tests/e2e_tests/e2e_test_client.cpp create mode 100644 test/network_tests/e2e_tests/e2e_test_client.hpp create mode 100755 test/network_tests/e2e_tests/e2e_test_external_master_start.sh create mode 100755 test/network_tests/e2e_tests/e2e_test_external_slave_start.sh create mode 100644 test/network_tests/e2e_tests/e2e_test_service.cpp create mode 100644 test/network_tests/e2e_tests/e2e_test_service.hpp create mode 100644 test/network_tests/event_tests/conf/event_test_master.json.in create mode 100644 test/network_tests/event_tests/conf/event_test_slave_tcp.json.in create mode 100644 test/network_tests/event_tests/conf/event_test_slave_udp.json.in create mode 100644 test/network_tests/event_tests/event_test_client.cpp create mode 100644 test/network_tests/event_tests/event_test_globals.hpp create mode 100755 test/network_tests/event_tests/event_test_master_starter.sh create mode 100644 test/network_tests/event_tests/event_test_service.cpp create mode 100755 test/network_tests/event_tests/event_test_slave_starter.sh create mode 100644 test/network_tests/header_factory_tests/header_factory_test.cpp create mode 100644 test/network_tests/header_factory_tests/header_factory_test_client.cpp create mode 100644 test/network_tests/header_factory_tests/header_factory_test_client.hpp create mode 100644 test/network_tests/header_factory_tests/header_factory_test_client.json create mode 100755 test/network_tests/header_factory_tests/header_factory_test_client_start.sh create mode 100755 test/network_tests/header_factory_tests/header_factory_test_send_receive_starter.sh create mode 100644 test/network_tests/header_factory_tests/header_factory_test_service.cpp create mode 100644 test/network_tests/header_factory_tests/header_factory_test_service.hpp create mode 100644 test/network_tests/header_factory_tests/header_factory_test_service.json create mode 100755 test/network_tests/header_factory_tests/header_factory_test_service_start.sh create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_udp.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_udp.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_master.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_slave.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_udp.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_udp.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_master.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_slave.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_master.json.in create mode 100644 test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_slave.json.in create mode 100644 test/network_tests/initial_event_tests/initial_event_test_availability_checker.cpp create mode 100644 test/network_tests/initial_event_tests/initial_event_test_client.cpp create mode 100644 test/network_tests/initial_event_tests/initial_event_test_globals.hpp create mode 100755 test/network_tests/initial_event_tests/initial_event_test_master_starter.sh create mode 100644 test/network_tests/initial_event_tests/initial_event_test_service.cpp create mode 100755 test/network_tests/initial_event_tests/initial_event_test_slave_starter.sh create mode 100644 test/network_tests/initial_event_tests/initial_event_test_stop_service.cpp create mode 100644 test/network_tests/magic_cookies_tests/conf/magic_cookies_test_client.json.in create mode 100644 test/network_tests/magic_cookies_tests/conf/magic_cookies_test_service.json.in create mode 100644 test/network_tests/magic_cookies_tests/magic_cookies_test_client.cpp create mode 100755 test/network_tests/magic_cookies_tests/magic_cookies_test_client_start.sh create mode 100644 test/network_tests/magic_cookies_tests/magic_cookies_test_service.cpp create mode 100755 test/network_tests/magic_cookies_tests/magic_cookies_test_service_start.sh create mode 100755 test/network_tests/magic_cookies_tests/magic_cookies_test_starter.sh create mode 100644 test/network_tests/malicious_data_tests/conf/malicious_data_test_master.json.in create mode 100755 test/network_tests/malicious_data_tests/conf/malicious_data_test_master_starter.sh.in create mode 100644 test/network_tests/malicious_data_tests/malicious_data_test_globals.hpp create mode 100644 test/network_tests/malicious_data_tests/malicious_data_test_msg_sender.cpp create mode 100644 test/network_tests/malicious_data_tests/malicious_data_test_service.cpp create mode 100644 test/network_tests/npdu_tests/conf/npdu_test_client_no_npdu.json.in create mode 100644 test/network_tests/npdu_tests/conf/npdu_test_client_npdu.json.in create mode 100644 test/network_tests/npdu_tests/conf/npdu_test_service_no_npdu.json.in create mode 100644 test/network_tests/npdu_tests/conf/npdu_test_service_npdu.json.in create mode 100644 test/network_tests/npdu_tests/npdu_test_client.cpp create mode 100644 test/network_tests/npdu_tests/npdu_test_client.hpp create mode 100755 test/network_tests/npdu_tests/npdu_test_client_no_npdu_start.sh create mode 100755 test/network_tests/npdu_tests/npdu_test_client_npdu_start.sh create mode 100644 test/network_tests/npdu_tests/npdu_test_globals.hpp create mode 100644 test/network_tests/npdu_tests/npdu_test_rmd.cpp create mode 100644 test/network_tests/npdu_tests/npdu_test_rmd.hpp create mode 100644 test/network_tests/npdu_tests/npdu_test_service.cpp create mode 100644 test/network_tests/npdu_tests/npdu_test_service.hpp create mode 100755 test/network_tests/npdu_tests/npdu_test_service_no_npdu_start.sh create mode 100755 test/network_tests/npdu_tests/npdu_test_service_npdu_start.sh create mode 100755 test/network_tests/npdu_tests/npdu_test_starter.sh create mode 100644 test/network_tests/offer_tests/conf/offer_test_big_sd_msg_master.json.in create mode 100755 test/network_tests/offer_tests/conf/offer_test_big_sd_msg_master_starter.sh.in create mode 100644 test/network_tests/offer_tests/conf/offer_test_big_sd_msg_slave.json.in create mode 100644 test/network_tests/offer_tests/conf/offer_test_external_master.json.in create mode 100755 test/network_tests/offer_tests/conf/offer_test_external_master_starter.sh.in create mode 100644 test/network_tests/offer_tests/conf/offer_test_external_slave.json.in create mode 100644 test/network_tests/offer_tests/offer_test_big_sd_msg_client.cpp create mode 100644 test/network_tests/offer_tests/offer_test_big_sd_msg_service.cpp create mode 100755 test/network_tests/offer_tests/offer_test_big_sd_msg_slave_starter.sh create mode 100644 test/network_tests/offer_tests/offer_test_client.cpp create mode 100644 test/network_tests/offer_tests/offer_test_external_sd_msg_sender.cpp create mode 100755 test/network_tests/offer_tests/offer_test_external_slave_starter.sh create mode 100644 test/network_tests/offer_tests/offer_test_globals.hpp create mode 100644 test/network_tests/offer_tests/offer_test_local.json create mode 100755 test/network_tests/offer_tests/offer_test_local_starter.sh create mode 100644 test/network_tests/offer_tests/offer_test_service.cpp create mode 100644 test/network_tests/offer_tests/offer_test_service_external.cpp create mode 100644 test/network_tests/offered_services_info_test/offered_services_info_test_client.cpp create mode 100644 test/network_tests/offered_services_info_test/offered_services_info_test_globals.hpp create mode 100644 test/network_tests/offered_services_info_test/offered_services_info_test_local.json create mode 100755 test/network_tests/offered_services_info_test/offered_services_info_test_local_starter.sh create mode 100644 test/network_tests/offered_services_info_test/offered_services_info_test_service.cpp create mode 100644 test/network_tests/payload_tests/conf/external_local_payload_test_client_external.json.in create mode 100644 test/network_tests/payload_tests/conf/external_local_payload_test_client_local.json.in create mode 100644 test/network_tests/payload_tests/conf/external_local_payload_test_service.json.in create mode 100755 test/network_tests/payload_tests/external_local_payload_test_client_external_start.sh create mode 100755 test/network_tests/payload_tests/external_local_payload_test_client_external_starter.sh create mode 100755 test/network_tests/payload_tests/external_local_payload_test_client_local_and_external_starter.sh create mode 100755 test/network_tests/payload_tests/external_local_payload_test_client_local_start.sh create mode 100755 test/network_tests/payload_tests/external_local_payload_test_client_local_starter.sh create mode 100755 test/network_tests/payload_tests/external_local_payload_test_service_client_external_start.sh create mode 100755 test/network_tests/payload_tests/external_local_payload_test_service_start.sh create mode 100644 test/network_tests/payload_tests/local_payload_test_client.json create mode 100755 test/network_tests/payload_tests/local_payload_test_client_start.sh create mode 100755 test/network_tests/payload_tests/local_payload_test_huge_payload_starter.sh create mode 100644 test/network_tests/payload_tests/local_payload_test_service.json create mode 100755 test/network_tests/payload_tests/local_payload_test_service_start.sh create mode 100755 test/network_tests/payload_tests/local_payload_test_starter.sh create mode 100644 test/network_tests/payload_tests/payload_test_client.cpp create mode 100644 test/network_tests/payload_tests/payload_test_client.hpp create mode 100644 test/network_tests/payload_tests/payload_test_service.cpp create mode 100644 test/network_tests/payload_tests/payload_test_service.hpp create mode 100644 test/network_tests/payload_tests/stopwatch.cpp create mode 100644 test/network_tests/payload_tests/stopwatch.hpp create mode 100644 test/network_tests/pending_subscription_tests/conf/pending_subscription_test_master.json.in create mode 100755 test/network_tests/pending_subscription_tests/conf/pending_subscription_test_master_starter.sh.in create mode 100644 test/network_tests/pending_subscription_tests/pending_subscription_test_globals.hpp create mode 100644 test/network_tests/pending_subscription_tests/pending_subscription_test_sd_msg_sender.cpp create mode 100644 test/network_tests/pending_subscription_tests/pending_subscription_test_service.cpp create mode 100644 test/network_tests/readme.txt create mode 100644 test/network_tests/restart_routing_tests/restart_routing_test_autoconfig.json create mode 100644 test/network_tests/restart_routing_tests/restart_routing_test_client.cpp create mode 100644 test/network_tests/restart_routing_tests/restart_routing_test_client.hpp create mode 100644 test/network_tests/restart_routing_tests/restart_routing_test_client.json create mode 100755 test/network_tests/restart_routing_tests/restart_routing_test_client_start.sh create mode 100644 test/network_tests/restart_routing_tests/restart_routing_test_service.cpp create mode 100644 test/network_tests/restart_routing_tests/restart_routing_test_service.hpp create mode 100644 test/network_tests/restart_routing_tests/restart_routing_test_service.json create mode 100755 test/network_tests/restart_routing_tests/restart_routing_test_service_start.sh create mode 100755 test/network_tests/restart_routing_tests/restart_routing_test_starter.sh create mode 100644 test/network_tests/routing_tests/conf/external_local_routing_test_client_external.json.in create mode 100644 test/network_tests/routing_tests/conf/external_local_routing_test_service.json.in create mode 100755 test/network_tests/routing_tests/conf/local_routing_test_starter.sh.bat.in create mode 100755 test/network_tests/routing_tests/conf/local_routing_test_starter.sh.in create mode 100755 test/network_tests/routing_tests/external_local_routing_test_client_external_start.sh create mode 100644 test/network_tests/routing_tests/external_local_routing_test_service.cpp create mode 100644 test/network_tests/routing_tests/external_local_routing_test_service.hpp create mode 100755 test/network_tests/routing_tests/external_local_routing_test_service_start.sh create mode 100755 test/network_tests/routing_tests/external_local_routing_test_starter.sh create mode 100644 test/network_tests/routing_tests/local_routing_test_client.cpp create mode 100644 test/network_tests/routing_tests/local_routing_test_client.hpp create mode 100644 test/network_tests/routing_tests/local_routing_test_client.json create mode 100755 test/network_tests/routing_tests/local_routing_test_client_start.sh create mode 100644 test/network_tests/routing_tests/local_routing_test_service.cpp create mode 100644 test/network_tests/routing_tests/local_routing_test_service.hpp create mode 100644 test/network_tests/routing_tests/local_routing_test_service.json create mode 100755 test/network_tests/routing_tests/local_routing_test_service_start.sh create mode 100644 test/network_tests/second_address_tests/conf/second_address_test_master_client.json.in create mode 100644 test/network_tests/second_address_tests/conf/second_address_test_master_service_udp.json.in create mode 100644 test/network_tests/second_address_tests/conf/second_address_test_slave_client.json.in create mode 100644 test/network_tests/second_address_tests/conf/second_address_test_slave_service_udp.json.in create mode 100755 test/network_tests/second_address_tests/conf/second_address_test_slave_starter.sh.in create mode 100644 test/network_tests/second_address_tests/second_address_test_client.cpp create mode 100644 test/network_tests/second_address_tests/second_address_test_globals.hpp create mode 100755 test/network_tests/second_address_tests/second_address_test_master_starter.sh create mode 100644 test/network_tests/second_address_tests/second_address_test_service.cpp create mode 100644 test/network_tests/security_tests/conf/security_test_config_client_external_allow.json.in create mode 100644 test/network_tests/security_tests/conf/security_test_config_client_external_deny.json.in create mode 100644 test/network_tests/security_tests/conf/security_test_config_service_external_allow.json.in create mode 100644 test/network_tests/security_tests/conf/security_test_config_service_external_deny.json.in create mode 100644 test/network_tests/security_tests/conf/security_test_local_config.json.in create mode 100644 test/network_tests/security_tests/security_test_client.cpp create mode 100644 test/network_tests/security_tests/security_test_client.hpp create mode 100755 test/network_tests/security_tests/security_test_external_master_start.sh create mode 100755 test/network_tests/security_tests/security_test_external_slave_start.sh create mode 100755 test/network_tests/security_tests/security_test_local_start.sh create mode 100644 test/network_tests/security_tests/security_test_service.cpp create mode 100644 test/network_tests/security_tests/security_test_service.hpp create mode 100644 test/network_tests/someip_test_globals.hpp create mode 100644 test/network_tests/someip_tp_tests/conf/someip_tp_test_master.json.in create mode 100755 test/network_tests/someip_tp_tests/conf/someip_tp_test_master_starter.sh.in create mode 100644 test/network_tests/someip_tp_tests/someip_tp_test_globals.hpp create mode 100644 test/network_tests/someip_tp_tests/someip_tp_test_msg_sender.cpp create mode 100644 test/network_tests/someip_tp_tests/someip_tp_test_service.cpp create mode 100644 test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master.json.in create mode 100644 test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json.in create mode 100644 test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json.in create mode 100644 test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json.in create mode 100644 test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_globals.hpp create mode 100755 test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh create mode 100644 test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_service.cpp create mode 100755 test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_udp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_udp_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_master.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_master_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_slave.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_slave_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_udp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_udp_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_udp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_udp_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_master.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_master_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_tcp_slave.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_tcp_slave_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_udp_slave.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_udp_slave_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_master.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_master_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_slave.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_slave_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_master.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_master_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_slave.json.in create mode 100644 test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_slave_local_tcp.json.in create mode 100644 test/network_tests/subscribe_notify_tests/subscribe_notify_test_globals.hpp create mode 100755 test/network_tests/subscribe_notify_tests/subscribe_notify_test_master_starter.sh create mode 100644 test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_client.cpp create mode 100755 test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master_starter.sh create mode 100644 test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_service.cpp create mode 100755 test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh create mode 100644 test/network_tests/subscribe_notify_tests/subscribe_notify_test_service.cpp create mode 100755 test/network_tests/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh create mode 100644 test/network_tests/suspend_resume_tests/conf/suspend_resume_test_client.json.in create mode 100644 test/network_tests/suspend_resume_tests/conf/suspend_resume_test_service.json.in create mode 100644 test/network_tests/suspend_resume_tests/suspend_resume_test.hpp create mode 100644 test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp create mode 100755 test/network_tests/suspend_resume_tests/suspend_resume_test_master_starter.sh create mode 100644 test/network_tests/suspend_resume_tests/suspend_resume_test_service.cpp create mode 100755 test/network_tests/suspend_resume_tests/suspend_resume_test_slave_starter.sh delete mode 100644 test/npdu_tests/conf/npdu_test_client_no_npdu.json.in delete mode 100644 test/npdu_tests/conf/npdu_test_client_npdu.json.in delete mode 100644 test/npdu_tests/conf/npdu_test_service_no_npdu.json.in delete mode 100644 test/npdu_tests/conf/npdu_test_service_npdu.json.in delete mode 100644 test/npdu_tests/npdu_test_client.cpp delete mode 100644 test/npdu_tests/npdu_test_client.hpp delete mode 100755 test/npdu_tests/npdu_test_client_no_npdu_start.sh delete mode 100755 test/npdu_tests/npdu_test_client_npdu_start.sh delete mode 100644 test/npdu_tests/npdu_test_globals.hpp delete mode 100644 test/npdu_tests/npdu_test_rmd.cpp delete mode 100644 test/npdu_tests/npdu_test_rmd.hpp delete mode 100644 test/npdu_tests/npdu_test_service.cpp delete mode 100644 test/npdu_tests/npdu_test_service.hpp delete mode 100755 test/npdu_tests/npdu_test_service_no_npdu_start.sh delete mode 100755 test/npdu_tests/npdu_test_service_npdu_start.sh delete mode 100755 test/npdu_tests/npdu_test_starter.sh delete mode 100644 test/offer_tests/conf/offer_test_big_sd_msg_master.json.in delete mode 100755 test/offer_tests/conf/offer_test_big_sd_msg_master_starter.sh.in delete mode 100644 test/offer_tests/conf/offer_test_big_sd_msg_slave.json.in delete mode 100644 test/offer_tests/conf/offer_test_external_master.json.in delete mode 100755 test/offer_tests/conf/offer_test_external_master_starter.sh.in delete mode 100644 test/offer_tests/conf/offer_test_external_slave.json.in delete mode 100644 test/offer_tests/offer_test_big_sd_msg_client.cpp delete mode 100644 test/offer_tests/offer_test_big_sd_msg_service.cpp delete mode 100755 test/offer_tests/offer_test_big_sd_msg_slave_starter.sh delete mode 100644 test/offer_tests/offer_test_client.cpp delete mode 100644 test/offer_tests/offer_test_external_sd_msg_sender.cpp delete mode 100755 test/offer_tests/offer_test_external_slave_sd_starter.sh delete mode 100755 test/offer_tests/offer_test_external_slave_starter.sh delete mode 100644 test/offer_tests/offer_test_globals.hpp delete mode 100644 test/offer_tests/offer_test_local.json delete mode 100755 test/offer_tests/offer_test_local_starter.sh delete mode 100644 test/offer_tests/offer_test_service.cpp delete mode 100644 test/offer_tests/offer_test_service_availability_checker.cpp delete mode 100644 test/offer_tests/offer_test_service_external.cpp delete mode 100644 test/offered_services_info_test/offered_services_info_test_client.cpp delete mode 100644 test/offered_services_info_test/offered_services_info_test_globals.hpp delete mode 100644 test/offered_services_info_test/offered_services_info_test_local.json delete mode 100755 test/offered_services_info_test/offered_services_info_test_local_starter.sh delete mode 100644 test/offered_services_info_test/offered_services_info_test_service.cpp delete mode 100644 test/payload_tests/conf/external_local_payload_test_client_external.json.in delete mode 100644 test/payload_tests/conf/external_local_payload_test_client_local.json.in delete mode 100644 test/payload_tests/conf/external_local_payload_test_service.json.in delete mode 100755 test/payload_tests/external_local_payload_test_client_external_start.sh delete mode 100755 test/payload_tests/external_local_payload_test_client_external_starter.sh delete mode 100755 test/payload_tests/external_local_payload_test_client_local_and_external_starter.sh delete mode 100755 test/payload_tests/external_local_payload_test_client_local_start.sh delete mode 100755 test/payload_tests/external_local_payload_test_client_local_starter.sh delete mode 100755 test/payload_tests/external_local_payload_test_service_client_external_start.sh delete mode 100755 test/payload_tests/external_local_payload_test_service_start.sh delete mode 100644 test/payload_tests/local_payload_test_client.json delete mode 100755 test/payload_tests/local_payload_test_client_start.sh delete mode 100755 test/payload_tests/local_payload_test_huge_payload_starter.sh delete mode 100644 test/payload_tests/local_payload_test_service.json delete mode 100755 test/payload_tests/local_payload_test_service_start.sh delete mode 100755 test/payload_tests/local_payload_test_starter.sh delete mode 100644 test/payload_tests/payload_test_client.cpp delete mode 100644 test/payload_tests/payload_test_client.hpp delete mode 100644 test/payload_tests/payload_test_service.cpp delete mode 100644 test/payload_tests/payload_test_service.hpp delete mode 100644 test/payload_tests/stopwatch.cpp delete mode 100644 test/payload_tests/stopwatch.hpp delete mode 100644 test/pending_subscription_tests/conf/pending_subscription_test_master.json.in delete mode 100755 test/pending_subscription_tests/conf/pending_subscription_test_master_starter.sh.in delete mode 100644 test/pending_subscription_tests/pending_subscription_test_globals.hpp delete mode 100644 test/pending_subscription_tests/pending_subscription_test_sd_msg_sender.cpp delete mode 100644 test/pending_subscription_tests/pending_subscription_test_service.cpp delete mode 100644 test/readme.txt delete mode 100644 test/restart_routing_tests/restart_routing_test_autoconfig.json delete mode 100644 test/restart_routing_tests/restart_routing_test_client.cpp delete mode 100644 test/restart_routing_tests/restart_routing_test_client.hpp delete mode 100644 test/restart_routing_tests/restart_routing_test_client.json delete mode 100755 test/restart_routing_tests/restart_routing_test_client_start.sh delete mode 100644 test/restart_routing_tests/restart_routing_test_service.cpp delete mode 100644 test/restart_routing_tests/restart_routing_test_service.hpp delete mode 100644 test/restart_routing_tests/restart_routing_test_service.json delete mode 100755 test/restart_routing_tests/restart_routing_test_service_start.sh delete mode 100755 test/restart_routing_tests/restart_routing_test_starter.sh delete mode 100644 test/routing_tests/conf/external_local_routing_test_client_external.json.in delete mode 100644 test/routing_tests/conf/external_local_routing_test_service.json.in delete mode 100755 test/routing_tests/conf/local_routing_test_starter.sh.bat.in delete mode 100755 test/routing_tests/conf/local_routing_test_starter.sh.in delete mode 100755 test/routing_tests/external_local_routing_test_client_external_start.sh delete mode 100644 test/routing_tests/external_local_routing_test_service.cpp delete mode 100644 test/routing_tests/external_local_routing_test_service.hpp delete mode 100755 test/routing_tests/external_local_routing_test_service_start.sh delete mode 100755 test/routing_tests/external_local_routing_test_starter.sh delete mode 100644 test/routing_tests/local_routing_test_client.cpp delete mode 100644 test/routing_tests/local_routing_test_client.hpp delete mode 100644 test/routing_tests/local_routing_test_client.json delete mode 100755 test/routing_tests/local_routing_test_client_start.sh delete mode 100644 test/routing_tests/local_routing_test_service.cpp delete mode 100644 test/routing_tests/local_routing_test_service.hpp delete mode 100644 test/routing_tests/local_routing_test_service.json delete mode 100755 test/routing_tests/local_routing_test_service_start.sh delete mode 100644 test/second_address_tests/conf/second_address_test_master_client.json.in delete mode 100644 test/second_address_tests/conf/second_address_test_master_service_udp.json.in delete mode 100644 test/second_address_tests/conf/second_address_test_slave_client.json.in delete mode 100644 test/second_address_tests/conf/second_address_test_slave_service_udp.json.in delete mode 100755 test/second_address_tests/conf/second_address_test_slave_starter.sh.in delete mode 100644 test/second_address_tests/second_address_test_client.cpp delete mode 100644 test/second_address_tests/second_address_test_globals.hpp delete mode 100755 test/second_address_tests/second_address_test_master_starter.sh delete mode 100644 test/second_address_tests/second_address_test_service.cpp delete mode 100644 test/security_tests/conf/security_test_config_client_external_allow.json.in delete mode 100644 test/security_tests/conf/security_test_config_client_external_deny.json.in delete mode 100644 test/security_tests/conf/security_test_config_service_external_allow.json.in delete mode 100644 test/security_tests/conf/security_test_config_service_external_deny.json.in delete mode 100644 test/security_tests/conf/security_test_local_config.json.in delete mode 100644 test/security_tests/security_test_client.cpp delete mode 100644 test/security_tests/security_test_client.hpp delete mode 100755 test/security_tests/security_test_external_master_start.sh delete mode 100755 test/security_tests/security_test_external_slave_start.sh delete mode 100755 test/security_tests/security_test_local_start.sh delete mode 100644 test/security_tests/security_test_service.cpp delete mode 100644 test/security_tests/security_test_service.hpp delete mode 100644 test/someip_test_globals.hpp delete mode 100644 test/someip_tp_tests/conf/someip_tp_test_master.json.in delete mode 100755 test/someip_tp_tests/conf/someip_tp_test_master_starter.sh.in delete mode 100644 test/someip_tp_tests/someip_tp_test_globals.hpp delete mode 100644 test/someip_tp_tests/someip_tp_test_msg_sender.cpp delete mode 100644 test/someip_tp_tests/someip_tp_test_service.cpp delete mode 100644 test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master.json.in delete mode 100644 test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in delete mode 100644 test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json.in delete mode 100644 test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json.in delete mode 100644 test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in delete mode 100644 test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json.in delete mode 100644 test/subscribe_notify_one_tests/subscribe_notify_one_test_globals.hpp delete mode 100755 test/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh delete mode 100644 test/subscribe_notify_one_tests/subscribe_notify_one_test_service.cpp delete mode 100755 test/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_udp.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_master.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_slave.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_udp.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_udp.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_master.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_tcp_slave.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_udp_slave.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_master.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_slave.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_master.json.in delete mode 100644 test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_slave.json.in delete mode 100644 test/subscribe_notify_tests/subscribe_notify_test_globals.hpp delete mode 100755 test/subscribe_notify_tests/subscribe_notify_test_master_starter.sh delete mode 100644 test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_client.cpp delete mode 100755 test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master_starter.sh delete mode 100644 test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_service.cpp delete mode 100755 test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh delete mode 100644 test/subscribe_notify_tests/subscribe_notify_test_service.cpp delete mode 100755 test/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh delete mode 100644 test/suspend_resume_tests/conf/suspend_resume_test_client.json.in delete mode 100644 test/suspend_resume_tests/conf/suspend_resume_test_service.json.in delete mode 100644 test/suspend_resume_tests/suspend_resume_test.hpp delete mode 100644 test/suspend_resume_tests/suspend_resume_test_client.cpp delete mode 100755 test/suspend_resume_tests/suspend_resume_test_master_starter.sh delete mode 100644 test/suspend_resume_tests/suspend_resume_test_service.cpp delete mode 100755 test/suspend_resume_tests/suspend_resume_test_slave_starter.sh create mode 100644 test/unit_tests/CMakeLists.txt create mode 100644 test/unit_tests/main.cpp create mode 100644 test/unit_tests/security_tests/ut_check_credentials.cpp create mode 100644 test/unit_tests/security_tests/ut_check_routing_credentials.cpp create mode 100644 test/unit_tests/security_tests/ut_get_client_to_sec_client_mapping.cpp create mode 100644 test/unit_tests/security_tests/ut_get_clients.cpp create mode 100644 test/unit_tests/security_tests/ut_get_sec_client_to_clients_mapping.cpp create mode 100644 test/unit_tests/security_tests/ut_is_client_allowed.cpp create mode 100644 test/unit_tests/security_tests/ut_is_offer_allowed.cpp create mode 100644 test/unit_tests/security_tests/ut_is_policy_update_allowed.cpp create mode 100644 test/unit_tests/security_tests/ut_load_policies.cpp create mode 100644 test/unit_tests/security_tests/ut_load_security_update_whitelist.cpp create mode 100644 test/unit_tests/security_tests/ut_remove_client_to_sec_client_mapping.cpp create mode 100644 test/unit_tests/security_tests/ut_remove_security_policy.cpp diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml index c8e23ea..90e61eb 100644 --- a/.github/workflows/c-cpp.yml +++ b/.github/workflows/c-cpp.yml @@ -8,7 +8,7 @@ on: jobs: build: - runs-on: [ubuntu-18.04] + runs-on: [ubuntu-22.04] steps: - uses: actions/checkout@v2 diff --git a/AUTHORS b/AUTHORS index 632e479..cc7c126 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1 @@ -Bayerische Motoren Werke Aktiengesellschaft (BMW AG) \ No newline at end of file +Bayerische Motoren Werke Aktiengesellschaft (BMW AG) diff --git a/Android.bp b/Android.bp index 038c787..a6a9ba3 100644 --- a/Android.bp +++ b/Android.bp @@ -1,14 +1,19 @@ libvsomeip_srcs = [ "implementation/endpoints/**/*.cpp", - "implementation/logging/**/*.cpp", + "implementation/logger/**/*.cpp", "implementation/tracing/**/*.cpp", "implementation/message/**/*.cpp", "implementation/routing/**/*.cpp", "implementation/runtime/**/*.cpp", "implementation/utility/**/*.cpp", "implementation/plugin/**/*.cpp", + "implementation/protocol/**/*.cpp", "implementation/security/**/*.cpp", - "implementation/logger/**/*.cpp", +] + +libvsomeip_compat_srcs = [ + "implementation/compat/message/src/*.cpp", + "implementation/compat/runtime/src/*.cpp", ] libvsomeip_cfg_srcs = [ @@ -26,19 +31,8 @@ libvsomeip_sd_srcs = [ cc_defaults { name: "vsomeip_defaults", - header_libs: [ - "libboost_headers", - ], - - local_include_dirs: [ - "interface", - "implementation/helper/1.70", - ], - - rtti: true, - cppflags: [ - "-std=c++11", + "-std=c++14", "-fexceptions", "-Wno-non-virtual-dtor", "-Wno-unused-const-variable", @@ -51,7 +45,25 @@ cc_defaults { "-Wno-format", "-Wno-header-guard", "-Wno-overloaded-virtual", - "-Wno-implicit-fallthrough" + "-Wno-implicit-fallthrough", + "-Wno-error", + "-Wno-shorten-64-to-32", + "-D_GTHREAD_USE_MUTEX_INIT_FUNC", + "-D_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC", + ] +} + +cc_defaults { + name: "vsomeip_lib_defaults", + + cflags: [ + "-DVSOMEIP_BOOST_VERSION=107100", + "-DVSOMEIP_INTERNAL_SUPPRESS_DEPRECATED", + ], + + local_include_dirs: [ + "interface", + "implementation/helper" ] } @@ -62,53 +74,50 @@ cc_library_shared { srcs: libvsomeip_srcs, defaults: [ - "vsomeip_defaults" + "vsomeip_defaults", + "vsomeip_lib_defaults" ], cflags: [ - "-DWITHOUT_SYSTEMD" + "-DWITHOUT_SYSTEMD", + "-DVSOMEIP_COMPAT_VERSION=\"3.3.0\"", + "-DVSOMEIP_BASE_PATH=\"/vendor/run/someip/\"", + "-DUSE_DLT", ], - rtti: true, - - local_include_dirs: [ - "interface", - "implementation/helper/1.70" + ldflags: [ + "-Wl,-wrap,socket", + "-Wl,-wrap,accept" ], + rtti: true, + export_include_dirs: [ - "interface" + "interface" ], - static_libs: [ + shared_libs: [ "libboost_system", "libboost_thread", "libboost_filesystem", - ], - - shared_libs: [ "liblog", "libutils" ] } cc_library_shared { - name: "libvsomeip3-cfg", + name: "libvsomeip_cfg", vendor: true, srcs: libvsomeip_cfg_srcs, defaults: [ - "vsomeip_defaults" + "vsomeip_defaults", + "vsomeip_lib_defaults" ], rtti: true, - local_include_dirs: [ - "interface", - "implementation/helper/1.70" - ], - shared_libs: [ "libvsomeip3", "libboost_system", @@ -117,112 +126,61 @@ cc_library_shared { } cc_library_shared { - name: "libvsomeip3-e2e", + name: "libvsomeip_e2e", vendor: true, srcs: libvsomeip_e2e_srcs, defaults: [ - "vsomeip_defaults" + "vsomeip_defaults", + "vsomeip_lib_defaults" ], rtti: true, - local_include_dirs: [ - "interface", - "implementation/helper/1.70" - ], - shared_libs: [ - "libvsomeip3", - "liblog" + "libvsomeip3" ] } cc_library_shared { - name: "libvsomeip3-sd", + name: "libvsomeip_sd", vendor: true, srcs: libvsomeip_sd_srcs, defaults: [ - "vsomeip_defaults" + "vsomeip_defaults", + "vsomeip_lib_defaults" ], rtti: true, - local_include_dirs: [ - "interface", - "implementation/helper/1.70" - ], - shared_libs: [ "libvsomeip3", - "liblog", - "libboost_thread" + "libboost_system" ] } -cc_defaults { - name: "vsomeip_example_defaults", +cc_library_shared { + name: "libvsomeip", vendor: true, - owner: "ts", - - shared_libs: [ - "libvsomeip3" - ], -} - -cc_binary { - name: "vsomeip-helloworld-client", - defaults: ["vsomeip_example_defaults"], - - srcs: [ - "examples/hello_world/hello_world_client_main.cpp", - ], -} -cc_binary { - name: "vsomeip-helloworld-service", - defaults: ["vsomeip_example_defaults"], + srcs: libvsomeip_compat_srcs, - srcs: [ - "examples/hello_world/hello_world_service_main.cpp", - ], -} - -cc_binary { - name: "vsomeip-notify-sample", - defaults: ["vsomeip_example_defaults"], - - srcs: [ - "examples/notify-sample.cpp", - ], -} - -cc_binary { - name: "vsomeip-request-sample", - defaults: ["vsomeip_example_defaults"], - - srcs: [ - "examples/request-sample.cpp", + defaults: [ + "vsomeip_defaults", + "vsomeip_lib_defaults" ], -} -cc_binary { - name: "vsomeip-response-sample", - defaults: ["vsomeip_example_defaults"], + rtti: true, - srcs: [ - "examples/response-sample.cpp", + export_include_dirs: [ + "interface" ], -} - -cc_binary { - name: "vsomeip-subscribe-sample", - defaults: ["vsomeip_example_defaults"], - srcs: [ - "examples/subscribe-sample.cpp", - ], + shared_libs: [ + "libvsomeip3", + "libboost_system" + ] } diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..720165b --- /dev/null +++ b/Android.mk @@ -0,0 +1,214 @@ +# Cannot convert to Android.bp as resource copying has not +# yet implemented for soong as of 12/16/2016 + +LOCAL_PATH := $(call my-dir) + +# config/vsomeip.json config file +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := vsomeip.json +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vsomeip +LOCAL_SRC_FILES := config/vsomeip.json +LOCAL_PROPRIETARY_MODULE := true +#include $(BUILD_PREBUILT) + +# config/vsomeip-local.json config file +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := vsomeip-local.json +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vsomeip +LOCAL_SRC_FILES := config/vsomeip-local.json +LOCAL_PROPRIETARY_MODULE := true +#include $(BUILD_PREBUILT) + +# config/vsomeip-tcp-client.json config file +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := vsomeip-tcp-client.json +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vsomeip +LOCAL_SRC_FILES := config/vsomeip-tcp-client.json +LOCAL_PROPRIETARY_MODULE := true +#include $(BUILD_PREBUILT) + +# config/vsomeip-tcp-service.json config file +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := vsomeip-tcp-service.json +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vsomeip +LOCAL_SRC_FILES := config/vsomeip-tcp-service.json +LOCAL_PROPRIETARY_MODULE := true +#include $(BUILD_PREBUILT) + +# config/vsomeip-udp-client.json config file +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := vsomeip-udp-client.json +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vsomeip +LOCAL_SRC_FILES := config/vsomeip-udp-client.json +LOCAL_PROPRIETARY_MODULE := true +#include $(BUILD_PREBUILT) + +# config/vsomeip-udp-service.json config file +include $(CLEAR_VARS) +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := vsomeip-udp-service.json +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/vsomeip +LOCAL_SRC_FILES := config/vsomeip-udp-service.json +LOCAL_PROPRIETARY_MODULE := true +#include $(BUILD_PREBUILT) + +# +# libvsomeip3_dlt +# +include $(CLEAR_VARS) + +LOCAL_MODULE := libvsomeip3_dlt +LOCAL_MODULE_TAGS := optional +LOCAL_CLANG := true +LOCAL_PROPRIETARY_MODULE := true + +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/interface \ + +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/endpoints) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/logger) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/tracing) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/message) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/routing) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/runtime) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/utility) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/plugin) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/security) + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/interface \ + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libutils \ + libboost_system \ + libboost_thread \ + libboost_filesystem \ + +LOCAL_CFLAGS := \ + -std=c++14 \ + -frtti \ + -fexceptions \ + -DWITHOUT_SYSTEMD \ + -DVSOMEIP_VERSION=\"3.3.0\" \ + -DVSOMEIP_BASE_PATH=\"/vendor/run/someip/\" \ + -Wno-unused-parameter \ + -Wno-non-virtual-dtor \ + -Wno-unused-const-variable \ + -Wno-unused-parameter \ + -Wno-unused-private-field \ + -Wno-unused-lambda-capture \ + -Wno-unused-variable \ + -Wno-unused-local-typedef \ + -Wno-sign-compare \ + -Wno-format \ + -Wno-header-guard \ + -Wno-overloaded-virtual \ + +include $(BUILD_SHARED_LIBRARY) + +# +# libvsomeip-cfg_dlt +# +include $(CLEAR_VARS) + +LOCAL_MODULE := libvsomeip-cfg_dlt +LOCAL_MODULE_TAGS := optional +LOCAL_CLANG := true +LOCAL_PROPRIETARY_MODULE := true + +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/interface \ + +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/configuration) + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/interface \ + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libutils \ + libboost_system \ + libboost_thread \ + libboost_filesystem \ + libvsomeip3_dlt \ + +LOCAL_CFLAGS := \ + -std=c++14 \ + -frtti \ + -fexceptions \ + -DWITHOUT_SYSTEMD \ + -DVSOMEIP_VERSION=\"3.3.0\" \ + -DVSOMEIP_BASE_PATH=\"/vendor/run/someip/\" \ + -Wno-unused-parameter \ + -Wno-non-virtual-dtor \ + -Wno-unused-const-variable \ + -Wno-unused-parameter \ + -Wno-unused-private-field \ + -Wno-unused-lambda-capture \ + -Wno-unused-variable \ + -Wno-unused-local-typedef \ + -Wno-sign-compare \ + -Wno-format \ + -Wno-header-guard \ + -Wno-overloaded-virtual \ + +include $(BUILD_SHARED_LIBRARY) + +# +# libvsomeip_dlt +# +include $(CLEAR_VARS) + +LOCAL_MODULE := libvsomeip_dlt +LOCAL_MODULE_TAGS := optional +LOCAL_CLANG := true +LOCAL_PROPRIETARY_MODULE := true + +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/interface \ + +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/compat/message) +LOCAL_SRC_FILES += $(call all-cpp-files-under,implementation/compat/runtime) + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/interface \ + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libutils \ + libboost_system \ + libboost_thread \ + libboost_filesystem \ + libvsomeip3_dlt \ + +LOCAL_CFLAGS := \ + -frtti \ + -fexceptions \ + -DWITHOUT_SYSTEMD \ + -DVSOMEIP_VERSION=\"3.3.0\" \ + -DVSOMEIP_COMPAT_VERSION=\"3.3.0\" \ + -DVSOMEIP_BASE_PATH=\"/vendor/run/someip/\" \ + -Wno-unused-parameter \ + -Wno-non-virtual-dtor \ + -Wno-unused-const-variable \ + -Wno-unused-parameter \ + -Wno-unused-private-field \ + -Wno-unused-lambda-capture \ + -Wno-unused-variable \ + -Wno-unused-local-typedef \ + -Wno-sign-compare \ + -Wno-format \ + -Wno-header-guard \ + -Wno-overloaded-virtual \ + -Wl,-wrap,socket \ + +include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/CHANGES b/CHANGES index f5868f9..2b917d0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,147 +1,240 @@ Changes ======= -v3.1.37.1 -- Support REQUEST_ACK message type (PR #237) -- Fix typo in error message (PR #238) -- Fix for bug #239, as one process use two stubs for different vlans (PR #247, Issues #223 #239 #241) -- Fix multicast timeout crash on Windows caused by bad use of reinterpret_cast (PR #272) -- Update configuration paths to reside on vendor partition (PR #274) -- Retry failed netlink operations (PR #283) -- Fixed android build error (PR #288) -- Fix for configuration option deserialize bug (PR #300, Issue #263) -- Accept return codes within range 0x20-0x5E as valid (PR #312) -- Add support for broadcast (PR #314) -- Fix for TC8 test case SOMEIPSRV_RPC_07 and SOMEIPSRV_SD_BEHAVIOR_03 (PR #316, Issue #315) -- Support boost 1.76 (PR #318) -- Fix big endian support in byteorder.hpp (PR #320) -- Use Reference to Prevent Copying (PR #356) -- Add CI using github actions (PR #140) - -v3.1.37 -- Added dependency from network tests to e2e library (plugin). -- Avoid services becoming available when the daemon is suspended -- Handling with some udp errors in send_cbk process, - restarting the connection. - -v3.1.36 -- Fix for ELVIS-339712: Fix handling of subscription objects - during unsubscribe. - -v3.1.35 -- Reworked fix for ELVIS-3310053 -- Improve checking for matching responses. - - When sending a response, vSomeIP only checked for a request with - the corresponding combination of client and session identifiers. - - This led to the possibility, that a response was sent for the - wrong service and/or method because of matching client and session - identifiers. - - This commit implements a full check of service, method, client and - session identifiers to ensure a response fits to the received - request. -- Rework to get rid of clang-tidy (llvm14) warnings. -- Facilitate manual execution of (some) subscription tests. - - Switch log level from "debug" to "warning" to facilitate the selection - of the script name that must be executed on client side. -- Do not send initial events for rejected subscriptions. - -v3.1.34 -- Use default ports if an acceptance configuration does not specify any. -- Prevent StopSubscribe/Subscribe on first offer reception. -- Ignore routing state settings to the current state. -- Explicitely clean subscriptions if a service removal is reported. -- Use SOL_RECBUFFORCE instead of SOL_RECVBUF. - -v3.1.33 -- Corrected flag initialization to avoid wait time when re-establishing - connections. - -v3.1.32 -- Fix bug which could lead to deleting requested services of routing - manager. -- Add Jenkins pipeline. -- Fix race condition which could lead to false positive security - warnings. -- Fix handling of remote subscriptions for unoffered services: Fix bug - which could lead to erroneously not accepting remote subscriptions - after a service was stop being offered and offered again. - -v3.1.31 + +v3.3.0 +- Do not erase while iterating. +- Changed invalid call of deserialize to serialize +- Fixed the the problem in policy::deserialize counts down the given policy size, +and after deserializing the policy it is 0. +- Monitor session IDs in SD messages and log missing IDs +- Fix timestamp format of log message +- Prevent crash when logging with DLT +- load_security_update_whitelist Unit and Benchmark Tests +- Added protection when a message is destroyed. +- Rework the addition of services when in suspended mode +- Remove const qualifier from function return types +- Adapt to boost 1.81.0 +- Removed VSOMEIP_DEPRECATED_UID_GID from some elements. +- Add nullptr guards to receive_cbk. +- Add nullptr check to receive_cbk. +- Fix network test build for g++11.3. +- Remove mutexes from logger_impl and security_impl. +- Fix VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE buffer. +- Fix range-loop-construct warning for g++11.3. +- Implementation of support for header-only tracing. +- Fix applied regarding the timeout in endpoints connections. +- Use standard reliability_type_e on service_discovery_impl. +- Added receive operation for UDP server endpoints. +- Reduce log level of some vsomeip messages. +- Change dependency on LINK UP. +- Change rejoining mechanism in UDP server endpoint. +- Fixed android build issues +- Added more DLT log info on credentials error +- Fixed ICON register issues. +- Added an unlocked method to get the policy extension path +- Manage E2E Profile04 counters per instance +- Fix handling of subscription objects during unsubscribe. +- Remove subscription on connection resets. +- Reuse local client ports. +- Add try block in message deserialization. +- Remove unneeded / unused structure servicegroup. +- Optimize event/field registration. +- Add dependency from network tests to e2e library (plugin). +- re-introduce the definition of socket timeout. +- pu/event-tests: Avoid deadlock. +- Linux: avoid static initialization of std::mutex. +- Improve robustness when stopping initial-event tests. +- Fixed various unused-variable warnings. +- Handling with some udp errors in send_cbk process. +- Avoid services becoming available when the daemon is suspended. +- refactor: remove `set_bound_sec_client()` from `local_tcp_server_endpoint_impl`. +- Refactor `plugin_manager_impl::load_symbol()` +- Use consistent naming for `security::is_client_allowed_to_access()` +- Raise C++ standard used to C++17 on non-Windows platforms +- Prefer using reinterpret_cast instead of C-style casts +- DRYer approach to loading `libvsomeip_sec` hook functions +- Indent with 4-spaces +- Hide `symbol_table` inside `security::load()` +- `policy_manager::get()` should call `policy_manager_impl::get()` +- Fix integer conversion warning +- Refine silencing MSVC warning C4101 +- Add `VSOMEIP_DISABLE_SECURITY` in a few remaining spots +- Add support for `vsomeip_sec_client_t` to subscription handlers +- Disable security unit/benchmark tests when `DISABLE_SECURITY` +- Disable security network tests when `DISABLE_SECURITY` +- Make the sec client a member of the connection +- Add support for TCP clients in the default security hooks +- Fix security checks when using internal TCP sockets +- Introduced protocol classes +- Extended interface to allow application specific configurations +- Allow to switch off internal routing +- Added ACL plugin +- Respect subscription status handler for ANY_EVENT +- Corrected handling of ANY_[SERVICE|INSTANCE|EVENTGROUP|EVENT] when handling subscription status +- Fix handling of lock files +- Add subnet support for IPv6 networks (boost 1.66+ only for now) +- Fix client specific debouncing +- Set SO_REUSEADDR before binding socket +- Specify local IP/interface when joining multicast group +- Avoid false positives when warning about not having loaded acceptance data +- Extended buffer size adaptation for UDP sockets +- Removed leftover from attempt to fix setsockopt blocking +- Implemented a cache for is_client_allowed +- Adapted version in OSS information +- Log errors (connection reset, end of file, bad descriptor) as such +- Rename extended "subscribe" method to "subscribe_with_debounce" + +v3.2.15 +- Unit/Benchmark tests for Security::Check Credentials +- Client dependent usage of session handling +- Fix Windows build +- Fix for multicast_socket bug +- Fixed spam messages of security policy extensions +- Added OSS information for RSE + +v3.2.14 +- Implementation of support for header-only tracing +- Replaced exceptions with error messages +- Asynchronously set join/leave options +- React on failed option setting +- Prevented StopSubscribe/Subscribe on first offer reception +- Implemented a cache for is_client_allowed operations + +v3.2.13 +- Fixed lock_guard and mutexes on lazy load policies + +v3.2.12 +- Fixed race condition on startup of suspend_resume_test +- Added a default initialize in tcp_client_endpoint_impl::is_sending +- Updated the log "Maximum number of dispatchers exceeded" +- Refactored the policy extensions map +- Added protection for Received buffer size and buffer capacity +- Added nullptr checks to some pointers in the eventgroupinfo +- Fixed Windows build +- Removed print error messages for unneeded endpoints +- Wrapped accept method to use accept4 +- Improved reliability of multicast leave group + +v3.2.11 +- Fix incorrect load of policies +- Fix unlocked access to multicast_info +- Rework the join mechanism. +- Fix receiving of routing info messages in TCP mode. +- Make routing client port range configurable ("routing-client-ports"). +- Allow to configure event update properties. + +v3.2.10.1 +- Fix false positive security warning + +v3.2.10 - Fix race condition which could lead to not establishing a TCP connection to a remote service -v3.1.30 +v3.2.9 +- Send StopSubscribe and clear subscribed_ map on STR +- Added suspend/resume test +- Erase subscribed_ map on received StopOffer +- Select new local port on bind error for uce + +v3.2.8 +- Fixed credentials::receive_credentials() error handling +- Ensured to call prepare_stop handler for TCP server endpoints + +v3.2.7 - Fixed lock order inversion -- Fixed UDP socket bind error handling -v3.1.29 -- Do not send re-subscriptions on suspend +v3.2.6 +- Adapted helloworld references within user guide +- Added nullptr check for remote subscription pointers -v3.1.28 +v3.2.5 - Fixed race condition in client endpoint send queue - Improved robustness when receiving malformed remote subscriptions - Cleanup remote subscribers on suspend - -v3.1.27 -- Performance improvement: Added service partitioning: - Each configured partition will lead to a separate client port being used - to connect to a remote server port -- Improve handling of expired subscriptions -- Fixed race condition when starting "last message received" - timer. - -v3.1.26 -- Improve handling of expired subscriptions - -v3.1.25 +- Make sure that the connection (and thus the policy loading) + has taken place before checking something against the policies + +v3.2.4 +- Removed load of the vsomeip_ext policies from the start +- Allow to partition service instances. Each partition uses a separate client + port, even if service instances from different partitions are offered on the + same server port of a remote device. +- Fixed timer restart (detection of last received SD message) +- Optimized distribution of credentials- Improve handling of expired subscriptions - Fix event payload caching at proxy - -v3.1.24 +- Select a free client port that was not used recently +- Fixed invalid insertion in known_clients_ map +- Fixed clearing of client endpoints +- Rework for expire_subscriptions() +- Rework map insertions +- Avoid deadlocks during expiration of subscriptions + +v3.2.3 +- Optimized updating the sent counter for FindService messages in requested_ map +- Improved log messages +- Enabled tracing for initial values of shadow events for subsequent subscribers. +- Reduced the vsomeip security logging +- Fixed race condition in the logger - Fix for initial events - -v3.1.23 - Fixed crash in TCP client endpoint - Fixed TCP socket bind error handling - -v3.1.22 -- Fixed joining multicast group for udp server endpoints - -v3.1.21 -- Fixed missing DLT logs if DLT was enabled in config in parallel with file or console logging. -- Avoid heap-buffer-overflow in look_ahead() when deserializing SD entry / option type. -- Restart UDP client endpoint on connection refused error. -- Select a free client port that was not used recently. -- Limit the number of possible remote subscribers from same remote IP address - to an eventgroup provided by a service/instance if the remote - subscriber uses different ports for its subscriptions. - -v3.1.20.3 -- Correct detection payload changes (Issue #164) - -v3.1.20.2 -- Removed special way of detecting boost within NDK (PR #187) -- Allow events/eventgroups to be specified in arbitrary order (Issue #68) -- Allow port 65536 to be used (Issue #80) -- Support IPv6 (Issue #162, PR #179) -- Fix handling of local service history (Issue #163) -- Fix referencing of placeholder events (Issue #175) -- Corrected handling of debounced requests when releasing (Issue #181) -- Fixed possible race when disconnecting (Issue #182) -- Align order of acknowledgement and value sending (Issue #183) - -v3.1.20.1 -- CMakeLists.txt fixes - (by Martin Haase) -- Mark all services unavailable when the routing manager goes down - (by Philip Werner & dannyrhubarb) - -v3.1.20 -- SomeIP/TP optimization -- Fix for expired subscriptions - -v3.1.19 -- Log statistics for high frequent received remote events -- Avoid unintended deletion of all service instances in release_service() -- Prevent deletion of server endpoint on SubscribeEventGroupACK with multicast endpoint +- Selected new local port on bind error for tce. +- Ignored subscribes when suspended +- Added subscriber count to log / extended config switches +- Limited subscriptions to same service, instance, eventgroup depending on remote IP +- Synchronized update_remote_subscription / send_(un)subscription() +- Fixed lazy loading on daemon + +v3.2.2 +- Fixed the loading of the security policies at the start +- Fixed the tags in the android logging +- Added the additional client ports in the ipsec-plugin default configuration +- Removed the unneeded socket option IPPROTO_IP/IPPKTINFO. +- Removed the libdlt dependency from android +- Improved the documentation of debouncer configuration. +- Check the port to send notifications +- Fixed the nullptr on multicast_socket +- Improved the sending of STOP_OFFER messages + +v3.2.1 +- Updated cmake minimum required version +- Fixed expire_subscriptions(address) +- Updated examples +- Ensured to clear previous error before calling dlsym (plugin_manager) +- Always send values after subscription acknowledgment- +- Added support to logs in Android +- Updated android build files +- Ensured to forward logs to DLT independently of FILE / CONSOLE log configuration +- Avoided heap-buffer-overflow in look_ahead() when deserializing SD entry +- Adapted the reader of the config to put always logging in Android +- Used error code when starting main phase timer +- Added some SomeIP/TP optimization +- Changed the loglevel for blocked incoming notifications +- Restarted UDP client endpoint on connection refused error +- Acquired mutex before change sd_acceptance_rules_active_ +- Fixed getEnv returning empty value + +v3.2.0 +- Dropped support for boost 1.65 and below - Do not lock the multicast mutex twice +- Disable warnings for boost and DLT headers +- Fix security credentials update in rm::proxy +- Prevent deletion of server endpoint +- Fix instance removal in local_services_history_ map +- Lazy load security policies +- Use a configuration variable for the SOME/IP-TP maximum segment length +- Use instance based SOME/IP-TP configuration +- Use service configuration within server endpoint +- Ensure maximum segment length is a multiple of 16 (SIP_RPC_772) +- Use configured separation times +- Added debounce test and refined debouncing +- Fix hostname transmission +- Do _NOT_ remove subscription on a received StopOffer +- serviceinfo: Removed unused & undefined member group_ +- Implemented socket wrapper using ld(1)'s "--wrap" +- Set the android LOG_TAG to VSIP +- Added message statistics +- Reworked android logging v3.1.18 - Support boost 1.74 @@ -156,10 +249,6 @@ v3.1.17 - Fixed race condition between service instances offered on the same endpoint(s). -v3.1.16.1 -- Restore IPv6 within UDP server endpoint -- AOSP build adaptation to vsomeip3 libraries - v3.1.16 - Fixed race condition when leaving multicast group - Do not busy loop when receiving garbage data on local endpoint @@ -170,30 +259,13 @@ v3.1.15 - Speedup security policy handling - Enable building with boost v1.73.0 -v3.1.14.1 -- Merged extended support for static routing (versioning) - (by Jean-Patrice Laude jean-patrice.laude@renault.com) -- Merged simplification of build process for hello_world example - (by Nikolay Khilyuk nkh@ua.fm) -- Updated Android.bp to use boost 1.70 or higher -- Merged Android support for hello_world example - (by Nikolay Khilyuk nkh@ua.fm) -- Align response sample to documentation (do not specify application name) - (by JayHou houjie@lixiang.com) -- Call dlerror before calling dlsym to clear previous error - (by Oleg Kharitonov Oleg.Kharitonov@elektrobit.com) -- Get base path from environment variable for Android NDK - (by Nikolay Khilyuk nkh@ua.fm) -- Fixed wrong library naming - (by Nikolay Khilyuk nkh@ua.fm) - v3.1.14 - Fixed race conditions (application registration, subscription) v3.1.13 - Abort operation when doing a full rejoin - Protect access when consuming a policy -- Decrease wait time for composite send operations +- Decrease wait time for composite send operations - Reimplemented logger without using boost::log v3.1.12 @@ -227,10 +299,10 @@ v3.1.7 v3.1.6 - Fix possible busy loop when expiring subscriptions - Use set of serializers to avoid deadlock situation -- Improve client identifier handling +- Improve client identifier handling - Check whether corresponding socket is available - Implement retry if a client identifier cannot be used -- Log buffer fill levels if they exceed a configurable threshold (default=67%). +- Log buffer fill levels if they exceed a configurable threshold (default=67%). v3.1.5 - Ensure subscriptions to remote services are correctly reset when @@ -506,7 +578,7 @@ v2.10.20 v2.10.19 - Catch exceptions on shutdown (especially from boost::log) -- Fixed handling of malformed packets in TCP client endpoint in conjunction +- Fixed handling of malformed packets in TCP client endpoint in conjunction with magic cookies v2.10.18 @@ -921,8 +993,8 @@ v2.2.2 to be used for unicasts instead of relying on the configured routes v2.2.1 -- Backward compatibility fixes - +- Backward compatibility fixes + v2.2.0 - Implemented Peer-to-Peer data exchange for notifications - Fixed handling of minor version during service discovery @@ -1037,7 +1109,7 @@ v1.3.0 v1.2.0 - Added (optional) thread pool for distribution of messages to the application -- Made configuration of service groups optional (as it is unneeded in pure +- Made configuration of service groups optional (as it is unneeded in pure client applications) - Support specification of transportation mode (reliable (TCP) / unreliable (UDP)) when creating messages diff --git a/CMakeLists.txt b/CMakeLists.txt index 36cf6ac..6b00041 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,16 +3,16 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -cmake_minimum_required (VERSION 2.8.12...3.23.3) +cmake_minimum_required (VERSION 3.10) project (vsomeip) set (VSOMEIP_NAME vsomeip3) set (VSOMEIP_COMPAT_NAME vsomeip) set (VSOMEIP_MAJOR_VERSION 3) -set (VSOMEIP_MINOR_VERSION 1) -set (VSOMEIP_PATCH_VERSION 37) -set (VSOMEIP_HOTFIX_VERSION 1) +set (VSOMEIP_MINOR_VERSION 3) +set (VSOMEIP_PATCH_VERSION 0) +set (VSOMEIP_HOTFIX_VERSION 0) set (VSOMEIP_VERSION ${VSOMEIP_MAJOR_VERSION}.${VSOMEIP_MINOR_VERSION}.${VSOMEIP_PATCH_VERSION}) set (PACKAGE_VERSION ${VSOMEIP_VERSION}) # Used in documentation/doxygen.in @@ -31,9 +31,9 @@ endif() ################################################################################################### # Offer the user the choice of overriding the installation directories -set (INSTALL_LIB_DIR lib CACHE STRING "Installation directory for libraries") -set (INSTALL_BIN_DIR bin CACHE STRING "Installation directory for executables") -set (INSTALL_INCLUDE_DIR include CACHE STRING "Installation directory for header files") +set (INSTALL_LIB_DIR lib CACHE PATH "Installation directory for libraries") +set (INSTALL_BIN_DIR bin CACHE PATH "Installation directory for executables") +set (INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files") if (WIN32 AND NOT CYGWIN) set (DEF_INSTALL_CMAKE_DIR CMake) @@ -41,7 +41,15 @@ else () set (DEF_INSTALL_CMAKE_DIR lib/cmake/${VSOMEIP_NAME}) endif () -set (INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE STRING "Installation directory for CMake files") +set (INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files") + +# Make relative paths absolute (needed later on) +foreach (p LIB BIN INCLUDE CMAKE) + set (var INSTALL_${p}_DIR) + if (NOT IS_ABSOLUTE "${${var}}") + set (ABSOLUTE_${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") # Add all targets to the build-tree export set + endif () +endforeach () ################################################################################################### # Set a default build type if none was specified @@ -55,27 +63,24 @@ endif() # OS if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") - set(OS "LINUX") set(DL_LIBRARY "dl") + +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # This is only relevant for GCC and causes warnings on Clang set(EXPORTSYMBOLS "-Wl,-export-dynamic -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exportmap.gcc") - set(NO_DEPRECATED "") - set(OPTIMIZE "") - set(OS_CXX_FLAGS "-D_GLIBCXX_USE_NANOSLEEP -pthread -O -Wall -Wextra -Wformat -Wformat-security -Wconversion -fexceptions -fstrict-aliasing -fstack-protector-strong -fasynchronous-unwind-tables -fno-omit-frame-pointer -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security -fPIE -pie -Wl,-z,relro,-z,now") -endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set(OS_CXX_FLAGS "${OS_CXX_FLAGS} -pie -Wl,-z,relro,-z,now") +endif() -if (${CMAKE_SYSTEM_NAME} MATCHES "Android") - set(OS "ANDROID") - set(DL_LIBRARY "") - set(EXPORTSYMBOLS "") set(NO_DEPRECATED "") set(OPTIMIZE "") + set(OS_CXX_FLAGS "${OS_CXX_FLAGS} -D_GLIBCXX_USE_NANOSLEEP -pthread -O -Wall -Wextra -Wformat -Wformat-security -Wconversion -fexceptions -fstrict-aliasing -fstack-protector-strong -fasynchronous-unwind-tables -fno-omit-frame-pointer -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Wpedantic -Werror -fPIE") - find_library(ANDROID_LOG_LIB log) - set(OS_LIBS ${ANDROID_LOG_LIB}) -endif(${CMAKE_SYSTEM_NAME} MATCHES "Android") + # force all use of std::mutex and std::recursive_mutex to use runtime init + # instead of static initialization so mutexes can be hooked to enable PI as needed + add_definitions(-D_GTHREAD_USE_MUTEX_INIT_FUNC -D_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC) +endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") - set(OS "FREEBSD") set(DL_LIBRARY "") set(EXPORTSYMBOLS "") set(NO_DEPRECATED "-Wno-deprecated") @@ -83,7 +88,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") set(OS_CXX_FLAGS "-pthread") endif (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") -################################################################################ +############################################My lib link flags#################################### # Options ################################################################################ @@ -99,19 +104,20 @@ if (ENABLE_SIGNAL_HANDLING) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_ENABLE_SIGNAL_HANDLING") endif () -# Sanitizer -if (ENABLE_THREAD_SANITIZER) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") -endif () +if (NOT MSVC) + # Sanitizer + if (ENABLE_THREAD_SANITIZER) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread") + endif () -if (ENABLE_LEAK_SANITIZER) -set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=leak") -endif () + if (ENABLE_LEAK_SANITIZER) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=leak") + endif () -# Configuration overlays -if (ENABLE_CONFIGURATION_OVERLAYS) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_ENABLE_CONFIGURATION_OVERLAYS") -endif () + if (ENABLE_PROFILING) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg") + endif () +endif (NOT MSVC) # Compatibility if (ENABLE_COMPAT) @@ -127,11 +133,14 @@ else () set (VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS 0) endif () -# Session handling configuration -if (ENABLE_SESSION_HANDLING_CONFIG) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_HAS_SESSION_HANDLING_CONFIG") +# Security / Policy handling +if (DISABLE_SECURITY) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_DISABLE_SECURITY") endif () +# Suppress deprecation warnings for vSomeIP interfaces +add_definitions(-DVSOMEIP_INTERNAL_SUPPRESS_DEPRECATED) + ################################################################################ # Dependencies ################################################################################ @@ -164,19 +173,14 @@ else() endif() message( STATUS "Using boost version: ${VSOMEIP_BOOST_VERSION}" ) -if (${VSOMEIP_BOOST_VERSION} GREATER 107600) -message( ERROR "boost version ${VSOMEIP_BOOST_VERSION} is not (yet) supported. Latest supported version is 1.76.0" ) -elseif(${VSOMEIP_BOOST_VERSION} GREATER 107500) -set(VSOMEIP_BOOST_HELPER implementation/helper/1.76) -elseif(${VSOMEIP_BOOST_VERSION} GREATER 107300) -set(VSOMEIP_BOOST_HELPER implementation/helper/1.74) -elseif(${VSOMEIP_BOOST_VERSION} GREATER 106999) -set(VSOMEIP_BOOST_HELPER implementation/helper/1.70) -elseif(${VSOMEIP_BOOST_VERSION} GREATER 106599) -set(VSOMEIP_BOOST_HELPER implementation/helper/1.66) -else() -set(VSOMEIP_BOOST_HELPER implementation/helper/1.55) -endif() + +if (${VSOMEIP_BOOST_VERSION} LESS 106600) +include_directories(SYSTEM + implementation/helper +) +endif () + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DVSOMEIP_BOOST_VERSION=${VSOMEIP_BOOST_VERSION}") find_package(PkgConfig) @@ -191,12 +195,10 @@ endif() # SystemD pkg_check_modules(SystemD "libsystemd") -if(NOT SystemD_FOUND OR ${CMAKE_SYSTEM_NAME} MATCHES "Android") +if(NOT SystemD_FOUND) MESSAGE( STATUS "Systemd was not found, watchdog disabled!") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWITHOUT_SYSTEMD") -else() -list(APPEND OS_LIBS ${SystemD_LIBRARIES}) -endif(NOT SystemD_FOUND OR ${CMAKE_SYSTEM_NAME} MATCHES "Android") +endif(NOT SystemD_FOUND) # Multiple routing managers if (VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS EQUAL 1) @@ -212,7 +214,6 @@ include_directories( ) include_directories(SYSTEM - ${VSOMEIP_BOOST_HELPER} ${DLT_INCLUDE_DIRS} ) @@ -230,16 +231,14 @@ if (MSVC) message("using MSVC Compiler") # add_definitions(-DVSOMEIP_DLL_COMPILATION) now it is controlled per target SET(BOOST_WINDOWS_VERSION "0x600" CACHE STRING "Set the same Version as the Version with which Boost was built, otherwise there will be errors. (normaly 0x600 is for Windows 7 and 0x501 is for Windows XP)") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32_WINNT=${BOOST_WINDOWS_VERSION} -DWIN32 -DBOOST_ASIO_DISABLE_IOCP /EHsc") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32_WINNT=${BOOST_WINDOWS_VERSION} -DWIN32 -DBOOST_ASIO_DISABLE_IOCP /EHsc") + # Disable warning C4250 since it warns that the compiler is correctly following the C++ Standard. It's a "We-Are-Doing-Things-By-The-Book" notice, not a real warning. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS -D_WIN32_WINNT=${BOOST_WINDOWS_VERSION} -DWIN32 -DBOOST_ASIO_DISABLE_IOCP /EHsc /std:c++latest /wd4250") set(USE_RT "") link_directories(${Boost_LIBRARY_DIR_DEBUG}) ADD_DEFINITIONS( -DBOOST_ALL_DYN_LINK ) else() - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D${OS} ${OS_CXX_FLAGS} -g ${OPTIMIZE} -std=c++11 ${NO_DEPRECATED} ${EXPORTSYMBOLS}") - if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Android") - set(USE_RT "rt") - endif() + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OS_CXX_FLAGS} -g ${OPTIMIZE} -std=c++14 ${NO_DEPRECATED} ${EXPORTSYMBOLS}") + set(USE_RT "rt") endif() ################################################################################ @@ -256,7 +255,7 @@ if (VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS EQUAL 0) set_target_properties(${VSOMEIP_NAME}-cfg PROPERTIES COMPILE_DEFINITIONS "VSOMEIP_DLL_COMPILATION_PLUGIN") endif() - target_link_libraries(${VSOMEIP_NAME}-cfg ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${OS_LIBS}) + target_link_libraries(${VSOMEIP_NAME}-cfg ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${SystemD_LIBRARIES}) endif () ################################################################################ @@ -268,6 +267,7 @@ file(GLOB ${VSOMEIP_NAME}_SRC "implementation/tracing/src/*.cpp" "implementation/message/src/*.cpp" "implementation/plugin/src/*.cpp" + "implementation/protocol/src/*.cpp" "implementation/routing/src/*.cpp" "implementation/runtime/src/*.cpp" "implementation/security/src/*.cpp" @@ -276,23 +276,30 @@ file(GLOB ${VSOMEIP_NAME}_SRC if (VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS EQUAL 1) list(APPEND ${VSOMEIP_NAME}_SRC "implementation/configuration/src/configuration_impl.cpp") endif() + +if (WIN32) +list(FILTER ${VSOMEIP_NAME}_SRC EXCLUDE REGEX ".*uds.*") +endif() + list(SORT ${VSOMEIP_NAME}_SRC) add_library(${VSOMEIP_NAME} SHARED ${${VSOMEIP_NAME}_SRC}) set_target_properties (${VSOMEIP_NAME} PROPERTIES VERSION ${VSOMEIP_VERSION} SOVERSION ${VSOMEIP_MAJOR_VERSION}) if (MSVC) set_target_properties(${VSOMEIP_NAME} PROPERTIES COMPILE_DEFINITIONS "VSOMEIP_DLL_COMPILATION") +else () + set_target_properties(${VSOMEIP_NAME} PROPERTIES LINK_FLAGS "-Wl,-wrap,socket -Wl,-wrap,accept") endif () target_include_directories(${VSOMEIP_NAME} INTERFACE $ $ $) # PRIVATE means the listed libraries won't be included in the "link interface", -# meaning the exported vsomeip3Targets.cmake targets won't try to link against +# meaning the exported ${VSOMEIP_NAME}Targets.cmake targets won't try to link against # them (which shouldn't be required). ${Boost_LIBRARIES} includes absolute # build host paths as of writing, which also makes this important as it breaks # the build. -target_link_libraries(${VSOMEIP_NAME} PRIVATE ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${DLT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${OS_LIBS}) +target_link_libraries(${VSOMEIP_NAME} PRIVATE ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${DLT_LIBRARIES} ${SystemD_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) ################################################################################ # Service Discovery library @@ -308,7 +315,7 @@ if (MSVC) set_target_properties(${VSOMEIP_NAME}-sd PROPERTIES COMPILE_DEFINITIONS "VSOMEIP_DLL_COMPILATION_PLUGIN") endif () -target_link_libraries(${VSOMEIP_NAME}-sd ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${OS_LIBS}) +target_link_libraries(${VSOMEIP_NAME}-sd ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${SystemD_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) ################################################################################ @@ -325,7 +332,7 @@ if (MSVC) set_target_properties(${VSOMEIP_NAME}-e2e PROPERTIES COMPILE_DEFINITIONS "VSOMEIP_DLL_COMPILATION_PLUGIN") endif () -target_link_libraries(${VSOMEIP_NAME}-e2e ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${OS_LIBS}) +target_link_libraries(${VSOMEIP_NAME}-e2e ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${SystemD_LIBRARIES}) ################################################################################ # Compatibility library @@ -356,7 +363,7 @@ target_include_directories( $ # for generated files in build mode $ # for clients in install mode ) -target_link_libraries(${VSOMEIP_COMPAT_NAME} PRIVATE ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${OS_LIBS}) +target_link_libraries(${VSOMEIP_COMPAT_NAME} PRIVATE ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${USE_RT} ${DL_LIBRARY} ${SystemD_LIBRARIES}) endif () @@ -407,7 +414,7 @@ message("Predefined diagnosis address: ${VSOMEIP_DIAGNOSIS_ADDRESS}") ################################################################################ set(INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/interface/vsomeip") -file (GLOB_RECURSE vsomeip_INCLUDE RELATIVE ${INCLUDE_PATH} "interface/*.hpp" ) +file (GLOB_RECURSE vsomeip_INCLUDE RELATIVE ${INCLUDE_PATH} "interface/*.h*" ) list (SORT vsomeip_INCLUDE) foreach ( file ${vsomeip_INCLUDE} ) @@ -418,7 +425,7 @@ endforeach() install ( TARGETS ${VSOMEIP_NAME} # IMPORTANT: Add the vsomeip library to the "export-set" - EXPORT vsomeip3Targets + EXPORT ${VSOMEIP_NAME}Targets RUNTIME DESTINATION "${INSTALL_BIN_DIR}" COMPONENT LIBRARY DESTINATION "${INSTALL_LIB_DIR}" COMPONENT ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" @@ -485,15 +492,15 @@ install ( ) # Add all targets to the build-tree export set -export (TARGETS ${VSOMEIP_NAME} FILE "${PROJECT_BINARY_DIR}/vsomeip3Targets.cmake") +export (TARGETS ${VSOMEIP_NAME} FILE "${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}Targets.cmake") # Export the package for use from the build-tree # (this registers the build-tree with a global CMake-registry) export (PACKAGE ${VSOMEIP_NAME}) -# Create the vsomeip3Config.cmake and vsomeip3ConfigVersion files -configure_file (vsomeip3Config.cmake.in "${PROJECT_BINARY_DIR}/vsomeip3Config.cmake" @ONLY) -configure_file (vsomeip3ConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/vsomeip3ConfigVersion.cmake" @ONLY) +# Create the ${VSOMEIP_NAME}Config.cmake and ${VSOMEIP_NAME}ConfigVersion files +configure_file (${VSOMEIP_NAME}Config.cmake.in "${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}Config.cmake" @ONLY) +configure_file (${VSOMEIP_NAME}ConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}ConfigVersion.cmake" @ONLY) # configure internal.hpp for correct version number configure_file ( @@ -501,18 +508,18 @@ configure_file ( "${PROJECT_SOURCE_DIR}/implementation/configuration/include/internal.hpp" ) -# Install the vsomeip3Config.cmake and vsomeip3ConfigVersion.cmake +# Install the ${VSOMEIP_NAME}Config.cmake and ${VSOMEIP_NAME}ConfigVersion.cmake install ( FILES - "${PROJECT_BINARY_DIR}/vsomeip3Config.cmake" - "${PROJECT_BINARY_DIR}/vsomeip3ConfigVersion.cmake" + "${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}Config.cmake" + "${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}ConfigVersion.cmake" DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev ) # Install the export set for use with the install-tree install ( - EXPORT vsomeip3Targets + EXPORT ${VSOMEIP_NAME}Targets DESTINATION "${INSTALL_CMAKE_DIR}" COMPONENT dev ) @@ -581,32 +588,32 @@ endif() ############################################################################## # create pkg-config file if(NOT WIN32) - configure_file(vsomeip3.pc.in ${PROJECT_BINARY_DIR}/vsomeip3.pc @ONLY) - install(FILES ${PROJECT_BINARY_DIR}/vsomeip3.pc DESTINATION lib/pkgconfig) + configure_file(${VSOMEIP_NAME}.pc.in ${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}.pc @ONLY) + install(FILES ${PROJECT_BINARY_DIR}/${VSOMEIP_NAME}.pc DESTINATION lib/pkgconfig) endif() ############################################################################## -if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Android") - # build routing manager daemon (Non-Windows only) - if (NOT MSVC) - add_subdirectory( examples/routingmanagerd ) - endif() +# build routing manager daemon (Non-Windows only) +if (NOT MSVC) +add_subdirectory( examples/routingmanagerd ) +endif() - # build tools - add_custom_target( tools ) - add_subdirectory( tools ) +# build tools +add_custom_target( tools ) +add_subdirectory( tools ) - # build examples - add_custom_target( examples ) - add_subdirectory( examples EXCLUDE_FROM_ALL ) - add_custom_target( hello_world ) - add_subdirectory( examples/hello_world EXCLUDE_FROM_ALL ) -endif() +# build examples +add_custom_target( examples ) +add_subdirectory( examples EXCLUDE_FROM_ALL ) ############################################################################## # Test section ############################################################################## +############################################################################## +# google benchmark +find_package(benchmark) + ############################################################################## # google test @@ -654,9 +661,9 @@ SET(TEST_IP_SLAVE "${TEST_IP_DEFAULT_VALUE}" CACHE STRING if((${TEST_IP_MASTER} STREQUAL ${TEST_IP_DEFAULT_VALUE}) OR (${TEST_IP_SLAVE} STREQUAL ${TEST_IP_DEFAULT_VALUE})) message(WARNING "TEST_IP_MASTER and/or TEST_IP_SLAVE isn't set. " - "Only local tests will be runnable " - "Please specify them via for example " - "-DTEST_IP_MASTER=10.0.3.1 -DTEST_IP_SLAVE=10.0.3.125") + "Remote tests cannot be run. " + "To enable, please specify for example " + "-DTEST_IP_MASTER=10.0.3.1 -DTEST_IP_SLAVE=10.0.3.2") endif() SET(TEST_IP_SLAVE_SECOND "${TEST_IP_DEFAULT_VALUE}" CACHE STRING @@ -673,15 +680,7 @@ else() set(TEST_SECOND_ADDRESS "ON") endif() -set(TEST_E2E_PROFILE_04 "OFF" CACHE BOOL - "Controls whether E2E Profile 04 tests should run or not") -if (ENABLE_SESSION_HANDLING_CONFIG) - set(TEST_E2E_PROFILE_04 "ON") -else () - message(WARNING "ENABLE_SESSION_HANDLING_CONFIG isn't set. " - "Test of E2E Profile 04 is not enabled.") -endif () - +set(TEST_E2E_PROFILE_04 "ON") SET(TEST_UID_DEFAULT_VALUE "123456789") SET(TEST_UID "${TEST_UID_DEFAULT_VALUE}" CACHE STRING @@ -694,7 +693,8 @@ SET(TEST_SECURITY "ON" CACHE BOOL "Controls whether security tests should run or not") if((${TEST_UID} STREQUAL ${TEST_UID_DEFAULT_VALUE}) OR - (${TEST_GID} STREQUAL ${TEST_GID_DEFAULT_VALUE})) + (${TEST_GID} STREQUAL ${TEST_GID_DEFAULT_VALUE}) OR + DISABLE_SECURITY) message(WARNING "TEST_UID and/or TEST_GID isn't set. " "Security Tests are not runnable " "Please specify them for example " @@ -703,14 +703,27 @@ if((${TEST_UID} STREQUAL ${TEST_UID_DEFAULT_VALUE}) OR endif() add_custom_target(build_tests) -add_dependencies(build_tests vsomeip3) -add_dependencies(build_tests vsomeip3-e2e) -add_dependencies(build_tests vsomeip3-sd) set(CMAKE_CTEST_COMMAND ctest -V) add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) add_dependencies(check build_tests) +add_custom_target(build_network_tests) +add_dependencies(build_network_tests ${VSOMEIP_NAME}) +add_dependencies(build_network_tests ${VSOMEIP_NAME}-e2e) +add_dependencies(build_network_tests ${VSOMEIP_NAME}-sd) +add_dependencies(build_tests build_network_tests) + +add_custom_target(build_unit_tests) +add_dependencies(build_unit_tests ${VSOMEIP_NAME}) +add_dependencies(build_unit_tests ${VSOMEIP_NAME}-sd) +add_dependencies(build_tests build_unit_tests) + +add_custom_target(build_benchmark_tests) +add_dependencies(build_benchmark_tests ${VSOMEIP_NAME}) +add_dependencies(build_benchmark_tests ${VSOMEIP_NAME}-sd) +add_dependencies(build_tests build_benchmark_tests) + ############################################################################## # add test directory diff --git a/LICENSE b/LICENSE index 14e2f77..a612ad9 100644 --- a/LICENSE +++ b/LICENSE @@ -35,7 +35,7 @@ Mozilla Public License Version 2.0 means any form of the work other than Source Code Form. 1.7. "Larger Work" - means a work that combines Covered Software with other material, in + means a work that combines Covered Software with other material, in a separate file or files, that is not Covered Software. 1.8. "License" diff --git a/README.md b/README.md index 8036a11..70be229 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ### vsomeip ##### Copyright -Copyright (C) 2015-2017, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +Copyright (C) 2015-2022, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) ##### License @@ -15,29 +15,24 @@ The vsomeip stack implements the http://some-ip.com/ (Scalable service-Oriented MiddlewarE over IP (SOME/IP)) protocol. The stack consists out of: * a shared library for SOME/IP (`libvsomeip3.so`) -* a second shared library for SOME/IP's service discovery (`libvsomeip3-sd.so`) - which is loaded during runtime if the service discovery is enabled. +* a shared library for SOME/IP's configuration module (`libvsomeip3-cfg.so`) +* a shared library for SOME/IP's service discovery (`libvsomeip3-sd.so`) +* a shared library for SOME/IP's E2E protection module (`libvsomeip3-e2e.so`) + +Optional: + +* a shared library for compatibility with vsomeip v2 (`libvsomeip.so`) ##### Build Instructions for Linux ###### Dependencies -- A C++11 enabled compiler like gcc >= 4.8 is needed. +- A C++14 enabled compiler is needed (default for gcc >= v6.1). - vsomeip uses CMake as buildsystem. -- vsomeip uses Boost >= 1.55: - -Ubuntu 14.04: +- vsomeip uses Boost >= 1.55.0: -`sudo apt-get install libboost-system1.55-dev libboost-thread1.55-dev libboost-log1.55-dev` - -Ubuntu 12.04: a PPA is necessary to use version 1.54 of Boost: --- URL: https://launchpad.net/~boost-latest/+archive/ubuntu/ppa ---`sudo add-apt-repository ppa:boost-latest/ppa` ---`sudo apt-get install libboost-system1.55-dev libboost-thread1.55-dev - libboost-log1.55-dev` - -For the tests Google's test framework https://code.google.com/p/googletest/[gtest] in version 1.7.0 is needed. --- URL: https://googletest.googlecode.com/files/gtest-1.7.0.zip +For the tests Google's test framework https://code.google.com/p/googletest/[gtest] is needed. +-- URL: https://googletest.googlecode.com/files/gtest-.zip To build the documentation asciidoc, source-highlight, doxygen and graphviz is needed: --`sudo apt-get install asciidoc source-highlight doxygen graphviz` @@ -114,5 +109,6 @@ In order that the vsomeip library is also included in the Android image, the lib PRODUCT_PACKAGES += \ libvsomeip \ libvsomeip_cfg \ - libvsomeip_sd -``` \ No newline at end of file + libvsomeip_sd \ + libvsomeip_e2e \ +``` diff --git a/documentation/vsomeipProtocol b/documentation/vsomeipProtocol new file mode 100644 index 0000000..2fc905e --- /dev/null +++ b/documentation/vsomeipProtocol @@ -0,0 +1,372 @@ +vSomeIP command documentation +============================= + +VSOMEIP_ASSIGN_CLIENT (0x00) + +Command 00 +Version xx xx +Client xx xx +Size xx xx xx xx +Name xx ... xx ;#xx = Size + + +VSOMEIP_ASSIGN_CLIENT_ACK (0x01) + +Command 01 +Version xx xx +Client xx xx +Size 02 00 00 00 +Assigned xx xx + + +VSOMEIP_REGISTER_APPLICATION (0x02) + +Command 02 +Version xx xx +Client xx xx +Size 00 00 00 00 + + +VSOMEIP_DEREGISTER_APPLICATION (0x03) + +Command 03 +Version xx xx +Client xx xx +Size 00 00 00 00 + + +VSOMEIP_APPLICATION_LOST (0x04) + + + + +VSOMEIP_ROUTING_INFO (0x05) + +Command 05 +Version xx xx +Client xx xx +Size xx xx xx xx +Entries + SubCommand xx ; RIE_ADD_CLIENT (0x0) or RIE_DEL_CLIENT (0x1) + Size xx xx xx xx + Client xx xx + [Address] xx .. xx ; Size - sizeof(Client) - sizeof(Port) + [Port] xx + + SubCommand xx ; RIE_ADD_SERVICE_INSTANCE (0x2) or RIE_DEL_SERVICE_INSTANCE (0x3) + Size xx xx xx xx ; Command size + Size xx xx xx xx ; Client info size + Client xx xx + [Address] xx .. xx ; Client info size - sizeof(Client) - sizeof(Port) + [Port] xx + Size xx xx xx xx ; Services size + Service xx xx + Instance xx xx + Major xx + Minor xx xx xx xx + + +VSOMEIP_REGISTERED_ACK (0x06) + +Command 06 +Version xx xx +Client xx xx +Size 00 00 00 00 + + +VSOMEIP_PING (0x07) + +Command 07 +Version xx xx +Client 00 00 +Size 00 00 00 00 + + +VSOMEIP_PONG (0x08) + +Command 08 +Version xx xx +Client xx xx +Size 00 00 00 00 + + +VSOMEIP_OFFER_SERVICE (0x10) + +Command 10 +Version xx xx +Client xx xx +Size 09 00 00 00 +Service xx xx +Instance xx xx +Major xx +Minor xx xx xx xx + + +VSOMEIP_STOP_OFFER_SERVICE (0x11) + +Command 11 +Version xx xx +Client xx xx +Size 09 00 00 00 +Service xx xx +Instance xx xx +Major xx +Minor xx xx xx xx + + +VSOMEIP_SUBSCRIBE (0x12) + +Command 12 +Version xx xx +Client xx xx +Size xx xx xx xx +Service xx xx +Instance xx xx +Eventgroup xx xx +Major xx +Event xx xx +Pending ID xx xx +Filter + OnChange xx + OnChangeResetsInterval xx + Interval xx xx xx xx xx xx xx xx + Ignore (per entry) + Key xx xx xx xx xx xx xx xx + Value xx + + +VSOMEIP_UNSUBSCRIBE (0x13) +VSOMEIP_EXPIRE (0x2A) + +Command 13/2A +Version xx xx +Client xx xx +Size 0a 00 00 00 +Service xx xx +Instance xx xx +Eventgroup xx xx +Event xx xx +Pending ID xx xx + + +VSOMEIP_REQUEST_SERVICE (0x14) + +Command 14 +Version xx xx +Client xx xx +Size xx xx xx xx +Entries + Service xx xx + Instance xx xx + Major xx + Minor xx xx xx xx + + +VSOMEIP_RELEASE_SERVICE (0x15) + +Command 15 +Version xx xx +Client xx xx +Size 04 00 00 00 +Service xx xx +Instance xx xx + + +VSOMEIP_SUBSCRIBE_NACK (0x16) + +Command 16 +Version xx xx +Client xx xx +Size 0c 00 00 00 +Service xx xx +Instance xx xx +Eventgroup xx xx +Subscriber xx xx +Event xx xx +ID xx xx + + +VSOMEIP_SUBSCRIBE_ACK (0x17) + +Command 17 +Version xx xx +Client xx xx +Size 0c 00 00 00 +Service xx xx +Instance xx xx +Eventgroup xx xx +Subscriber xx xx +Event xx xx +ID xx xx + + +VSOMEIP_SEND (0x18) +VSOMEIP_NOTIFY (0x19) +VSOMEIP_NOTIFY_ONE (0x1A) + +Command 18|19|1a +Version xx xx +Client xx xx +Size xx xx xx xx +Instance xx xx +Reliable xx ; UDP (00) or TCP (01) +Status xx ; CRC of E2E - protected messages +Destination xx xx ; Client ID of the receiver +Payload xx ... xx + + +VSOMEIP_REGISTER_EVENT (0x1B) + +Command 1b +Version xx xx +Client xx xx +Size xx xx xx xx ; 10 + #eventgroups * 2 +Entries + Service xx xx + Instance xx xx + Notifier xx xx + Type xx ; ET_EVENT (00), ET_SELECTIVE_EVENT(01) or ET_FIELD(02) + Provided xx ; False (00) or True (01) + Reliability xx ; UDP (00) or TCP (01) + IsCyclic xx + Num Eventgroups xx xx + Entries + Eventgroup xx xx + + +VSOMEIP_UNREGISTER_EVENT (0x1C) + +Command 1c +Version xx xx +Client xx xx +Size 07 00 00 00 +Service xx xx +Instance xx xx +Notifier xx xx +Provided xx + + +VSOMEIP_ID_RESPONSE (0x1D) + + + + +VSOMEIP_ID_REQUEST (0x1E) + + + + +VSOMEIP_OFFERED_SERVICES_REQUEST (0x1F) + +Command 1f +Version xx xx +Client xx xx +Size 01 00 00 00 +OfferType xx (00 = LOCAL, 01 = REMOTE, 02 = ALL) + + +VSOMEIP_OFFERED_SERVICES_RESPONSE (0x20) + +Command 20 +Version xx xx +Client xx xx +Size xx xx xx xx +OfferedServices + Subcommand xx (00 = ADD CLIENT, 01 = ADD SERVICE INSTANCE, 02 = DELETE SERVICE INSTANCE, 03 = DELETE CLIENT) + Size xx xx xx xx + ServiceInstances + Service xx xx + Instance xx xx + Major xx xx + Minor xx xx + + +VSOMEIP_UNSUBSCRIBE_ACK (0x21) + +Command 21 +Version xx xx +Client xx xx +Size 08 00 00 00 +Service xx xx +Instance xx xx +Eventgroup xx xx +Id xx xx + + +VSOMEIP_RESEND_PROVIDED_EVENTS (0x22) + +Command 22 +Version xx xx +Client xx xx +Size 04 00 00 00 +PendingOfferId xx xx xx xx + + +VSOMEIP_UPDATE_SECURITY_POLICY (0x23) +VSOMEIP_UPDATE_SECURITY_POLICY_INT (0x29) + +Command 23/29 +Version xx xx +Client xx xx +Size xx xx xx xx +UpdateId xx xx xx xx +Policy xx ... xx + + +VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE (0x24) + +Command 24 +Version xx xx +Client xx xx +Size 04 00 00 00 +UpdateId xx xx xx xx + + +VSOMEIP_REMOVE_SECURITY_POLICY (0x25) + +Command 25 +Version xx xx +Client xx xx +Size 0c 00 00 00 +UpdateId xx xx xx xx +Uid xx xx xx xx +Gid xx xx xx xx + + +VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE (0x26) + +Command 26 +Version xx xx +Client xx xx +Size 04 00 00 00 +UpdateId xx xx xx xx + + +VSOMEIP_UPDATE_SECURITY_CREDENTIALS (0x27) + +Command 27 +Version xx xx +Client xx xx +Size xx xx xx xx +Credentials + Uid xx xx xx xx + Gid xx xx xx xx + + +VSOMEIP_DISTRIBUTE_SECURITY_POLICIES (0x28) + +Command 28 +Version xx xx +Client xx xx xx xx +Size xx xx xx xx +PoliciesCount xx xx xx xx +Policies + Size xx xx xx xx + Data xx ... xx + + +VSOMEIP_SUSPEND (0x30) + +Command 30 +Version xx xx +Size xx xx xx xx \ No newline at end of file diff --git a/documentation/vsomeipUserGuide b/documentation/vsomeipUserGuide index dd4f13d..b98183a 100644 --- a/documentation/vsomeipUserGuide +++ b/documentation/vsomeipUserGuide @@ -15,7 +15,7 @@ vsomeip Copyright +++++++ -Copyright (C) 2015-2019, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +Copyright (C) 2015-2022, Bayerische Motoren Werke Aktiengesellschaft (BMW AG) License +++++++ @@ -42,7 +42,7 @@ Build Instructions ------------------ Dependencies ~~~~~~~~~~~~ -* A C++11 enabled compiler like gcc >= 5.2 is needed. +* A C++14 enabled compiler is needed (default for gcc >= v6.1) * vsomeip uses cmake as buildsystem. * vsomeip uses Boost >= 1.55: ** Ubuntu 14.04: @@ -144,15 +144,6 @@ to be ready to send/receive messages, call cmake like: cmake -DROUTING_READY_MESSAGE= .. ---- -Compilation with configuration overlays -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -To compile vsomeip with configuration overlays enabled, call cmake -like: -[source,bash] ----- -cmake -DENABLE_CONFIGURATION_OVERLAYS=1 .. ----- - Compilation with vSomeIP 2 compatibility layer ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ To compile vsomeip with enabled vSomeIP 2 compatibility layer, call @@ -272,6 +263,8 @@ On startup the following environment variables are read out: local configuration file `./vsomeip.json` and/or a local configuration folder `./vsomeip`. If `VSOMEIP_CONFIGURATION` is set to a valid file or directory path, this is used instead of the standard configuration (thus neither default nor local file/folder will be parsed). +* `VSOMEIP_CONFIGURATION_`: Application-specific version of `VSOMEIP_CONFIGURATION`. + Please note that must be valid as part of an environment variable. * `VSOMEIP_MANDATORY_CONFIGURATION_FILES`: vsomeip allows to specify mandatory configuration files to speed-up application startup. While mandatory configuration files are read by all applications, all other configuration files are only read by the application that is @@ -551,14 +544,6 @@ An application plug-in extends the functionality on application level. It gets i by vsomeip over the basic application states (INIT/START/STOP) and can, based on these notifications, access the standard "application"-API via the runtime. + -** 'overlay' (optional) -+ -Contains the path to a configuration that overwrites specific configuration elements -(unicast, netmask, device, network, diagnosis address & mask, service discovery) for the -application. This allows to manage different network addresses from a single process. -+ -NOTE: This feature is only available if vsomeip was compiled with ENABLE_CONFIGURATION_OVERLAYS. -+ * `services` (array) + Contains the services of the service provider. @@ -951,14 +936,15 @@ Event ID. *** `on_change` + -Specifies whether the event is only forwared on -paylaod change or not. (valid values: _true_, _false_). +Specifies whether the event is forwarded on +payload change or not. (valid values: _true_, _false_). +Default is _false_. *** `ignore` + Array of payload indexes with given bit mask (optional) to be ignored in payload change evaluation. -Instead of specifying an index / bitmask pair, one can only define the paylaod index +Instead of specifying an index / bitmask pair, one can only define the payload index which shall be ignored in the evaluation. **** `index` @@ -973,17 +959,64 @@ Example mask: 0x0f ignores payload changes in low nibble of the byte at given in *** `interval` + Specifies if the event shall be debounced based on elapsed time interval. -(valid values: _time in ms_, _never_). +(valid values: _time in ms_, _never_). Default is _never_. -*** `on_change_resets_interval_` (optional) +*** `on_change_resets_interval` (optional) Specifies if interval timer is reset when payload change was detected. -(valid values: _false_, _true_). +(valid values: _false_, _true_). Defaults to _false_. + +* `routing` (optional) ++ +Specifies the properties of the routing. Either a string that specifies the application that hosts the +routing component or a structure that specifies all properties of the routing. If the routing is not +specified, the first started application will host the routing component. + +** `host` ++ +Properties of the routing manager. + +*** `name` ++ +Name if the application that hosts the routing component. + +*** `uid` ++ +User identifier of the process that runs the routing component. Must be specified if credential checks +are enabled by _check_credentials_ set to true. + +*** `gid` ++ +Group identifier of the process that runs the routing component. Must be specified if credential checks +are enabled by _check_credentials_ set to true. + +*** `unicast` (optional) ++ +The unicast address that shall be used by the routing manager, if the internal communication shall be done +by using TCP connections. -* `routing` +*** `port` (optional) + -The name of the application that is responsible for the routing. +The port that shall be used by the routing manager, if the internal communication shall be done +by using TCP connections. -* `routing-credentials` +** `guests` (optional) ++ +Properties of all applications that do not host the routing component, if the internal communication shall be +done using TCP connections. + +*** `unicast` ++ +The unicast address that shall be used by the applications to connect to the routing manager. + +*** `ports` ++ +A set of port ranges that shall be used to connect to the routing manager. Each client application requires +two ports, one for receiving messages from other applications and one to send messages to other applications. +Notes: Each configured port range must contain an even number of ports. If an even port number is configured +to be the routing host port, the first port in the range must also be even. If an uneven port number is +configured to be the routing host port, the first port in the range must also be uneven. + +* `routing-credentials` (deprecated) + The UID / GID of the application acting as routing manager. (Must be specified if credentials checks are enabled using _check_credentials_ set to _true_ in order to successfully check the routing managers credentials passed on connect) @@ -1113,14 +1146,6 @@ Time which the stack collects new service offers before they enter the repetition phase. This can be used to reduce the number of sent messages during startup. The default setting is _500ms_. + - -** `max_remote_subscribers` -+ -Limit the number of possible remote subscribers from same remote IP address -to an eventgroup provided by a service/instance if the remote subscriber uses -different ports for its subscriptions. The default setting is _3_. -+ - //Watchdog * anchor:config-watchdog[]`watchdog` (optional) + @@ -1408,6 +1433,31 @@ They give a basic overview how to use the security related configuration tags de in this chapter to run a simple request/response or subscribe/notify example locally or remotely. + +Security policy extensions +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +vsomeip policy extension configuration supports the definition of paths that contain additional +security policies to be loaded whenever a client with a yet unknown hostname connects to a local server endpoint. +The following configuration parameters are available and can be defined in a file named `vsomeip_policy_extensions.json`. + +// Security policy extension +* anchor:config-policy-extension[]`container_policies` (optional array) ++ +Specifies the additional configuration folders to be loaded for each container hostname / filesystem path pair. + +** `container` ++ +Specifies the linux hostname. + +** `path` ++ +Specifies a filesystem path (relative to vsomeip_policy_extensions.json or absolute) which contains +$UID_$GID subfolders that hold a `vsomeip_security.json` file. +Note: ($UID / $GID is the UID /GID of the vsomeip client application +to which a client from hostname defined with `container`connetcs to. + + Audit Mode ~~~~~~~~~~ vsomeip's security implementation can be put in a so called 'Audit Mode' where @@ -1551,7 +1601,7 @@ Service [source, bash] ---- -include::../examples/hello_world/hello_world_service.cpp[] +include::../examples/hello_world/hello_world_service_main.cpp[] ---- The service example results in the following program execution: @@ -1634,7 +1684,7 @@ Client ~~~~~~ [source, bash] ---- -include::../examples/hello_world/hello_world_client.cpp[] +include::../examples/hello_world/hello_world_client_main.cpp[] ---- The client example results in the following program execution: @@ -1829,17 +1879,17 @@ Example: ---- // get trace connector std::shared_ptr its_connector - = vsomeip::trace::connector::get(); + = vsomeip::trace::connector::get(); // add channel std::shared_ptr its_channel - = its_connector->create_channel("MC", "My channel"); + = its_connector->create_channel("MC", "My channel"); // add filter rule vsomeip::trace::match_t its_match = std::make_tuple(0x1234, 0xffff, 0x80e8); vsomeip::trace::filter_id_t its_filter_id - = its_channel->add_filter(its_match, true); + = its_channel->add_filter(its_match, true); // init trace connector its_connector->init(); diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 4325ddd..3ce5483 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -3,8 +3,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -cmake_minimum_required (VERSION 2.8...3.23.2) - set(EXAMPLE_CONFIG_FILES "../config/vsomeip.json" "../config/vsomeip-local.json" diff --git a/examples/hello_world/Android.bp b/examples/hello_world/Android.bp index c7819c4..c095dc1 100644 --- a/examples/hello_world/Android.bp +++ b/examples/hello_world/Android.bp @@ -3,15 +3,15 @@ cc_defaults { vendor: true, cppflags: [ - "-std=c++11", + "-std=c++14", "-Wno-unused-parameter", ], shared_libs: [ "libvsomeip3", - "libvsomeip3-cfg", - "libvsomeip3-e2e", - "libvsomeip3-sd", + "libvsomeip_cfg", + "libvsomeip_e2e", + "libvsomeip_sd", "liblog", ], } @@ -33,10 +33,3 @@ cc_binary { "hello_world_client_main.cpp", ], } - -prebuilt_etc { - name: "helloworld-local.json", - vendor: true, - sub_dir: "vsomeip", - src: "helloworld-local.json", -} diff --git a/examples/hello_world/CMakeLists.txt b/examples/hello_world/CMakeLists.txt index 44bd45d..d6e222d 100644 --- a/examples/hello_world/CMakeLists.txt +++ b/examples/hello_world/CMakeLists.txt @@ -3,12 +3,14 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -cmake_minimum_required (VERSION 2.8.7...3.23.2) +cmake_minimum_required (VERSION 2.8.7) project (vSomeIPHelloWorld) find_package(Threads REQUIRED) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +set(VSOMEIP_NAME "vsomeip3") + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") include_directories(${VSOMEIP_INCLUDE_DIRS}) @@ -17,16 +19,17 @@ target_sources(vsomeip_hello_world_service INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/hello_world_service.hpp" ) target_include_directories(vsomeip_hello_world_service INTERFACE - "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}" ) add_library(vsomeip_hello_world_client INTERFACE) target_sources(vsomeip_hello_world_client INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/hello_world_client.hpp" ) + target_include_directories(vsomeip_hello_world_client INTERFACE - "${CMAKE_CURRENT_SOURCE_DIR}" - ) + "${CMAKE_CURRENT_SOURCE_DIR}" +) if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Android") # This will get us acces to diff --git a/examples/hello_world/readme b/examples/hello_world/readme index 1cb9d8f..afe92fd 100644 --- a/examples/hello_world/readme +++ b/examples/hello_world/readme @@ -18,8 +18,11 @@ sudo make install 2. Build hello_world target ___________________________ -cmake --build . --target hello_world -cd ./examples/hello_world/ +cd /examples/hello_world$: + +mkdir build +cd build +cmake .. make Running Hello World Example diff --git a/examples/notify-sample.cpp b/examples/notify-sample.cpp index 0b9ed52..2aafa9d 100644 --- a/examples/notify-sample.cpp +++ b/examples/notify-sample.cpp @@ -19,10 +19,9 @@ class service_sample { public: - service_sample(bool _use_tcp, uint32_t _cycle) : + service_sample(uint32_t _cycle) : app_(vsomeip::runtime::get()->create_application()), is_registered_(false), - use_tcp_(_use_tcp), cycle_(_cycle), blocked_(false), running_(true), @@ -166,12 +165,6 @@ public: } void notify() { - std::shared_ptr its_message - = vsomeip::runtime::get()->create_request(use_tcp_); - - its_message->set_service(SAMPLE_SERVICE_ID); - its_message->set_instance(SAMPLE_INSTANCE_ID); - its_message->set_method(SAMPLE_SET_METHOD_ID); vsomeip::byte_t its_data[10]; uint32_t its_size = 1; @@ -205,7 +198,6 @@ public: private: std::shared_ptr app_; bool is_registered_; - bool use_tcp_; uint32_t cycle_; std::mutex mutex_; @@ -235,23 +227,11 @@ private: #endif int main(int argc, char **argv) { - bool use_tcp = false; uint32_t cycle = 1000; // default 1s - std::string tcp_enable("--tcp"); - std::string udp_enable("--udp"); std::string cycle_arg("--cycle"); for (int i = 1; i < argc; i++) { - if (tcp_enable == argv[i]) { - use_tcp = true; - break; - } - if (udp_enable == argv[i]) { - use_tcp = false; - break; - } - if (cycle_arg == argv[i] && i + 1 < argc) { i++; std::stringstream converter; @@ -260,7 +240,7 @@ int main(int argc, char **argv) { } } - service_sample its_sample(use_tcp, cycle); + service_sample its_sample(cycle); #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING its_sample_ptr = &its_sample; signal(SIGINT, handle_signal); diff --git a/examples/request-sample.cpp b/examples/request-sample.cpp index 96eadfd..65d4b4c 100644 --- a/examples/request-sample.cpp +++ b/examples/request-sample.cpp @@ -64,7 +64,7 @@ public: std::shared_ptr< vsomeip::payload > its_payload = vsomeip::runtime::get()->create_payload(); std::vector< vsomeip::byte_t > its_payload_data; for (std::size_t i = 0; i < 10; ++i) - its_payload_data.push_back(static_cast(i % 256)); + its_payload_data.push_back(vsomeip::byte_t(i % 256)); its_payload->set_data(its_payload_data); request_->set_payload(its_payload); diff --git a/examples/response-sample.cpp b/examples/response-sample.cpp index 8b30302..6bd8ad2 100644 --- a/examples/response-sample.cpp +++ b/examples/response-sample.cpp @@ -107,7 +107,7 @@ public: = vsomeip::runtime::get()->create_payload(); std::vector its_payload_data; for (std::size_t i = 0; i < 120; ++i) - its_payload_data.push_back(static_cast(i % 256)); + its_payload_data.push_back(vsomeip::byte_t(i % 256)); its_payload->set_data(its_payload_data); its_response->set_payload(its_payload); diff --git a/examples/routingmanagerd/CMakeLists.txt b/examples/routingmanagerd/CMakeLists.txt index 51504e5..e0d85aa 100644 --- a/examples/routingmanagerd/CMakeLists.txt +++ b/examples/routingmanagerd/CMakeLists.txt @@ -3,8 +3,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -cmake_minimum_required (VERSION 2.8...3.23.2) - # Daemon add_executable(routingmanagerd routingmanagerd.cpp) target_link_libraries(routingmanagerd ${VSOMEIP_NAME} ${Boost_LIBRARIES} ${DL_LIBRARY} ${DLT_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) diff --git a/examples/routingmanagerd/routingmanagerd.cpp b/examples/routingmanagerd/routingmanagerd.cpp index b2118f6..7290808 100644 --- a/examples/routingmanagerd/routingmanagerd.cpp +++ b/examples/routingmanagerd/routingmanagerd.cpp @@ -16,8 +16,9 @@ #include #ifdef USE_DLT +#ifndef ANDROID #include - +#endif #endif static std::shared_ptr its_application; @@ -64,8 +65,10 @@ void routingmanagerd_stop(int _signal) { */ int routingmanagerd_process(bool _is_quiet) { #ifdef USE_DLT +#ifndef ANDROID if (!_is_quiet) DLT_REGISTER_APP(VSOMEIP_LOG_DEFAULT_APPLICATION_ID, VSOMEIP_LOG_DEFAULT_APPLICATION_NAME); +#endif #else (void)_is_quiet; #endif diff --git a/exportmap.gcc b/exportmap.gcc index a9a489c..8e8b99b 100644 --- a/exportmap.gcc +++ b/exportmap.gcc @@ -1,5 +1,5 @@ { -global: +global: extern "C++" { *vsomeip_v3::configuration; vsomeip_v3::configuration::*; @@ -25,6 +25,9 @@ global: *vsomeip_v3::payload_impl::*; *vsomeip_v3::policy_manager; vsomeip_v3::policy_manager::*; + *vsomeip_v3::policy_manager_impl; + vsomeip_v3::policy_manager_impl::*; + vsomeip_v3::security::authenticate_router; *vsomeip_v3::runtime; vsomeip_v3::runtime::get*; vsomeip_v3::runtime::set_property*; @@ -36,19 +39,13 @@ global: vsomeip_v3::eventgroupinfo::*; *vsomeip_v3::remote_subscription; vsomeip_v3::remote_subscription::*; - *vsomeip_v3::security; - vsomeip_v3::security::*; - *vsomeip_v3::security_impl; - vsomeip_v3::security_impl::*; - *vsomeip_v3::servicegroup; - vsomeip_v3::servicegroup::*; *vsomeip_v3::serviceinfo; vsomeip_v3::serviceinfo::*; *vsomeip_v3::sd::runtime; vsomeip_v3::sd::runtime::*; *vsomeip_v3::utility; vsomeip_v3::utility::is*; - vsomeip_v3::utility::parse*; + vsomeip_v3::utility::data*; *vsomeip_v3::plugin_manager; vsomeip_v3::plugin_manager::*; vsomeip_v3::tp::tp_reassembler::*; @@ -60,7 +57,7 @@ global: *vsomeip::runtime; vsomeip::logger::*; *vsomeip::logger; - }; + }; vsomeip_plugin_init; local: *; diff --git a/implementation/compat/runtime/src/application_impl.cpp b/implementation/compat/runtime/src/application_impl.cpp index ce65136..f1934e4 100644 --- a/implementation/compat/runtime/src/application_impl.cpp +++ b/implementation/compat/runtime/src/application_impl.cpp @@ -638,7 +638,7 @@ application_impl::is_selective_event( if (its_service != eventgroups_.end()) { const auto its_instance = its_service->second.find(_instance); if (its_instance != its_service->second.end()) { - for (const auto& eg : _eventgroups) { + for (const auto eg : _eventgroups) { const auto its_egrp = its_instance->second.find(eg); if (its_egrp != its_instance->second.end()) { is_selective = true; diff --git a/implementation/configuration/include/application_configuration.hpp b/implementation/configuration/include/application_configuration.hpp new file mode 100644 index 0000000..f20afd5 --- /dev/null +++ b/implementation/configuration/include/application_configuration.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_CFG_APPLICATION_CONFIGURATION_HPP_ +#define VSOMEIP_V3_CFG_APPLICATION_CONFIGURATION_HPP_ + +#include +#include + +#include +#include + +#ifdef ANDROID +#include "internal_android.hpp" +#else +#include "internal.hpp" +#endif + +namespace vsomeip_v3 { + +struct debounce_filter_t; + +namespace cfg { + +struct application_configuration { + client_t client_; + std::size_t max_dispatchers_; + std::size_t max_dispatch_time_; + std::size_t thread_count_; + std::size_t request_debouncing_; + std::map > plugins_; + int nice_level_; + debounce_configuration_t debounces_; + bool has_session_handling_; +}; + +} // namespace cfg +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_CFG_APPLICATION_CONFIGURATION_HPP_ diff --git a/implementation/configuration/include/client.hpp b/implementation/configuration/include/client.hpp index 872974f..5c0805d 100644 --- a/implementation/configuration/include/client.hpp +++ b/implementation/configuration/include/client.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/configuration/include/configuration.hpp b/implementation/configuration/include/configuration.hpp index e107e17..ef597e1 100644 --- a/implementation/configuration/include/configuration.hpp +++ b/implementation/configuration/include/configuration.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,13 +19,13 @@ #include #include #include +#include #include "trace.hpp" #include "../../e2e_protection/include/e2exf/config.hpp" #include "e2e.hpp" -#include "debounce.hpp" #ifdef ANDROID #include "internal_android.hpp" @@ -40,6 +40,7 @@ namespace vsomeip_v3 { class event; +struct debounce_filter_t; class configuration { public: @@ -51,6 +52,9 @@ public: #endif virtual bool load(const std::string &_name) = 0; +#ifndef VSOMEIP_DISABLE_SECURITY + virtual bool lazy_load_security(const std::string &_client_host) = 0; +#endif // !VSOMEIP_DISABLE_SECURITY virtual bool remote_offer_info_add(service_t _service, instance_t _instance, std::uint16_t _port, @@ -67,6 +71,7 @@ public: virtual const boost::asio::ip::address & get_unicast_address() const = 0; virtual const boost::asio::ip::address& get_netmask() const = 0; + virtual unsigned short get_prefix() const = 0; virtual const std::string &get_device() const = 0; virtual diagnosis_t get_diagnosis_address() const = 0; virtual diagnosis_t get_diagnosis_mask() const = 0; @@ -76,34 +81,35 @@ public: virtual bool has_console_log() const = 0; virtual bool has_file_log() const = 0; virtual bool has_dlt_log() const = 0; - virtual const std::string & get_logfile() const = 0; + virtual const std::string &get_logfile() const = 0; virtual logger::level_e get_loglevel() const = 0; - virtual const std::string & get_routing_host() const = 0; + virtual bool is_routing_enabled() const = 0; + virtual const std::string &get_routing_host_name() const = 0; + virtual const boost::asio::ip::address &get_routing_host_address() const = 0; + virtual port_t get_routing_host_port() const = 0; + + virtual const boost::asio::ip::address &get_routing_guest_address() const = 0; + virtual std::set > get_routing_guest_ports() const = 0; + + virtual bool is_local_routing() const = 0; virtual std::string get_unicast_address(service_t _service, instance_t _instance) const = 0; virtual uint16_t get_reliable_port(service_t _service, instance_t _instance) const = 0; - virtual bool has_enabled_magic_cookies(std::string _address, + virtual bool has_enabled_magic_cookies(const std::string &_address, uint16_t _port) const = 0; virtual uint16_t get_unreliable_port(service_t _service, instance_t _instance) const = 0; - virtual major_version_t get_major_version(service_t _service, - instance_t _instance) const = 0; - virtual minor_version_t get_minor_version(service_t _service, - instance_t _instance) const = 0; - virtual ttl_t get_ttl(service_t _service, - instance_t _instance) const = 0; - virtual void get_configured_timing_requests( - service_t _service, std::string _ip_target, + service_t _service, const std::string &_ip_target, std::uint16_t _port_target, method_t _method, std::chrono::nanoseconds *_debounce_time, std::chrono::nanoseconds *_max_retention_time) const = 0; virtual void get_configured_timing_responses( - service_t _service, std::string _ip_service, + service_t _service, const std::string &_ip_service, std::uint16_t _port_service, method_t _method, std::chrono::nanoseconds *_debounce_time, std::chrono::nanoseconds *_max_retention_time) const = 0; @@ -122,6 +128,11 @@ public: virtual uint8_t get_threshold(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const = 0; + virtual void get_event_update_properties( + service_t _service, instance_t _instance, event_t _event, + std::chrono::milliseconds &_cycle, + bool &_change_resets_cycle, bool &_update_on_change_) const = 0; + virtual client_t get_id(const std::string &_name) const = 0; virtual bool is_configured_client_id(client_t _id) const = 0; @@ -130,9 +141,7 @@ public: virtual std::size_t get_io_thread_count(const std::string &_name) const = 0; virtual int get_io_thread_nice_level(const std::string &_name) const = 0; virtual std::size_t get_request_debouncing(const std::string &_name) const = 0; -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG virtual bool has_session_handling(const std::string &_name) const = 0; -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG virtual std::uint32_t get_max_message_size_local() const = 0; virtual std::uint32_t get_max_message_size_reliable(const std::string& _address, @@ -140,7 +149,7 @@ public: virtual std::uint32_t get_max_message_size_unreliable() const = 0; virtual std::uint32_t get_buffer_shrink_threshold() const = 0; - virtual bool supports_selective_broadcasts(boost::asio::ip::address _address) const = 0; + virtual bool supports_selective_broadcasts(const boost::asio::ip::address &_address) const = 0; virtual bool is_offered_remote(service_t _service, instance_t _instance) const = 0; @@ -188,6 +197,10 @@ public: virtual void set_configuration_path(const std::string &_path) = 0; + virtual std::map get_additional_data( + const std::string &_application_name, + const std::string &_plugin_name) = 0; + //E2E virtual std::map> get_e2e_configuration() const = 0; virtual bool is_e2e_enabled() const = 0; @@ -199,17 +212,18 @@ public: virtual uint32_t get_log_status_interval() const = 0; // TTL factor - typedef std::uint32_t ttl_factor_t; - typedef std::map> ttl_map_t; + using ttl_factor_t = std::uint32_t; + using ttl_map_t = std::map>; virtual ttl_map_t get_ttl_factor_offers() const = 0; virtual ttl_map_t get_ttl_factor_subscribes() const = 0; // Debouncing - virtual std::shared_ptr get_debounce( + virtual std::shared_ptr get_debounce( + const std::string &_name, service_t _service, instance_t _instance, event_t _event) const = 0; // Queue size limit endpoints - typedef std::uint32_t endpoint_queue_limit_t; + using endpoint_queue_limit_t = std::uint32_t; virtual endpoint_queue_limit_t get_endpoint_queue_limit( const std::string& _address, std::uint16_t _port) const = 0; virtual endpoint_queue_limit_t get_endpoint_queue_limit_local() const = 0; @@ -227,13 +241,13 @@ public: const boost::asio::ip::address& _address, std::uint16_t _port, bool _reliable) const = 0; - typedef std::pair port_range_t; + using port_range_t = std::pair; virtual void set_sd_acceptance_rule( const boost::asio::ip::address &_address, port_range_t _port_range, port_type_e _type, const std::string &_path, bool _reliable, bool _enable, bool _default) = 0; - typedef std::map< + using sd_acceptance_rules_t = std::map< boost::asio::ip::address, // other device std::pair< std::string, // path to file that determines whether or not IPsec is active @@ -245,9 +259,7 @@ public: > > > - > sd_acceptance_rules_t; - virtual void set_sd_acceptance_rules(const sd_acceptance_rules_t& _rules, - bool _enable) = 0; + >; virtual sd_acceptance_rules_t get_sd_acceptance_rules() = 0; virtual void set_sd_acceptance_rules_active( const boost::asio::ip::address& _address, bool _enable) = 0; @@ -256,15 +268,19 @@ public: virtual int get_udp_receive_buffer_size() const = 0; - virtual bool check_routing_credentials(client_t _client, uint32_t _uid, uint32_t _gid) const = 0; + virtual bool check_routing_credentials(client_t _client, + const vsomeip_sec_client_t *_sec_client) const = 0; // SOME/IP-TP - virtual bool tp_segment_messages_client_to_service( - service_t _service, std::string _ip_target, - std::uint16_t _port_target, method_t _method) const = 0; - virtual bool tp_segment_messages_service_to_client( - service_t _service, std::string _ip_service, - std::uint16_t _port_service, method_t _method) const = 0; + virtual bool is_tp_client( + service_t _service, const std::string &_address, std::uint16_t _port, + method_t _method) const = 0; + virtual bool is_tp_service( + service_t _service, const std::string &_address, std::uint16_t _port, + method_t _method) const = 0; + virtual void get_tp_configuration( + service_t _service, instance_t _instance, method_t _method, bool _is_client, + std::uint16_t &_max_segment_length, std::uint32_t &_separation_time) const = 0; // routing shutdown timeout virtual std::uint32_t get_shutdown_timeout() const = 0; @@ -278,6 +294,17 @@ public: virtual partition_id_t get_partition_id( service_t _service, instance_t _instance) const = 0; + + virtual reliability_type_e get_reliability_type( + const boost::asio::ip::address &_reliable_address, + const uint16_t &_reliable_port, + const boost::asio::ip::address &_unreliable_address, + const uint16_t &_unreliable_port) const = 0; + + // security + virtual bool is_security_enabled() const = 0; + virtual bool is_security_audit() const = 0; + virtual bool is_remote_access_allowed() const = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/configuration/include/configuration_element.hpp b/implementation/configuration/include/configuration_element.hpp index 7daf9d7..2b650e3 100644 --- a/implementation/configuration/include/configuration_element.hpp +++ b/implementation/configuration/include/configuration_element.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -16,6 +16,16 @@ struct configuration_element { std::string name_; boost::property_tree::ptree tree_; + configuration_element(const std::string &_name, const boost::property_tree::ptree &_tree) noexcept + : name_(_name), + tree_(_tree) { + } + + configuration_element(configuration_element &&_source) noexcept + : name_(std::move(_source.name_)), + tree_(std::move(_source.tree_)) { + } + bool operator<(const configuration_element &_other) const { return (name_ < _other.name_); } diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp index cb6c284..9ae1c79 100644 --- a/implementation/configuration/include/configuration_impl.hpp +++ b/implementation/configuration/include/configuration_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,26 +6,30 @@ #ifndef VSOMEIP_V3_CFG_CONFIGURATION_IMPL_HPP #define VSOMEIP_V3_CFG_CONFIGURATION_IMPL_HPP +#include #include #include #include -#include #include -#include +#include #include -#include "trace.hpp" +#include "application_configuration.hpp" #include "configuration.hpp" #include "configuration_element.hpp" +#include "e2e.hpp" +#include "routing.hpp" #include "watchdog.hpp" #include "service_instance_range.hpp" +#include "trace.hpp" #include "../../e2e_protection/include/e2exf/config.hpp" -#include "e2e.hpp" -#include "debounce.hpp" #include "../../security/include/policy.hpp" namespace vsomeip_v3 { + +struct debounce_filter_t; + namespace cfg { struct client; @@ -39,11 +43,14 @@ class configuration_impl: public configuration, public std::enable_shared_from_this { public: - VSOMEIP_EXPORT configuration_impl(); + VSOMEIP_EXPORT configuration_impl(const std::string &_path); VSOMEIP_EXPORT configuration_impl(const configuration_impl &_other); VSOMEIP_EXPORT virtual ~configuration_impl(); VSOMEIP_EXPORT bool load(const std::string &_name); +#ifndef VSOMEIP_DISABLE_SECURITY + VSOMEIP_EXPORT bool lazy_load_security(const std::string &_client_host); +#endif // !VSOMEIP_DISABLE_SECURITY VSOMEIP_EXPORT bool remote_offer_info_add(service_t _service, instance_t _instance, std::uint16_t _port, @@ -62,6 +69,7 @@ public: VSOMEIP_EXPORT const boost::asio::ip::address & get_unicast_address() const; VSOMEIP_EXPORT const boost::asio::ip::address& get_netmask() const; + VSOMEIP_EXPORT unsigned short get_prefix() const; VSOMEIP_EXPORT const std::string &get_device() const; VSOMEIP_EXPORT unsigned short get_diagnosis_address() const; VSOMEIP_EXPORT std::uint16_t get_diagnosis_mask() const; @@ -77,24 +85,17 @@ public: VSOMEIP_EXPORT std::string get_unicast_address(service_t _service, instance_t _instance) const; VSOMEIP_EXPORT uint16_t get_reliable_port(service_t _service, instance_t _instance) const; - VSOMEIP_EXPORT bool has_enabled_magic_cookies(std::string _address, uint16_t _port) const; + VSOMEIP_EXPORT bool has_enabled_magic_cookies(const std::string &_address, uint16_t _port) const; VSOMEIP_EXPORT uint16_t get_unreliable_port(service_t _service, instance_t _instance) const; - VSOMEIP_EXPORT major_version_t get_major_version(service_t _service, - instance_t _instance) const; - VSOMEIP_EXPORT minor_version_t get_minor_version(service_t _service, - instance_t _instance) const; - VSOMEIP_EXPORT ttl_t get_ttl(service_t _service, - instance_t _instance) const; - VSOMEIP_EXPORT void get_configured_timing_requests( - service_t _service, std::string _ip_target, + service_t _service, const std::string &_ip_target, std::uint16_t _port_target, method_t _method, std::chrono::nanoseconds *_debounce_time, std::chrono::nanoseconds *_max_retention_time) const; VSOMEIP_EXPORT void get_configured_timing_responses( - service_t _service, std::string _ip_service, + service_t _service, const std::string &_ip_service, std::uint16_t _port_service, method_t _method, std::chrono::nanoseconds *_debounce_time, std::chrono::nanoseconds *_max_retention_time) const; @@ -105,7 +106,15 @@ public: uint16_t _remote_port, bool _reliable, std::map > &_used_client_ports, uint16_t &_client_port) const; - VSOMEIP_EXPORT const std::string & get_routing_host() const; + VSOMEIP_EXPORT bool is_routing_enabled() const; + VSOMEIP_EXPORT bool is_local_routing() const; + + VSOMEIP_EXPORT const std::string &get_routing_host_name() const; + VSOMEIP_EXPORT const boost::asio::ip::address &get_routing_host_address() const; + VSOMEIP_EXPORT port_t get_routing_host_port() const; + + VSOMEIP_EXPORT const boost::asio::ip::address &get_routing_guest_address() const; + VSOMEIP_EXPORT std::set > get_routing_guest_ports() const; VSOMEIP_EXPORT client_t get_id(const std::string &_name) const; VSOMEIP_EXPORT bool is_configured_client_id(client_t _id) const; @@ -125,13 +134,18 @@ public: VSOMEIP_EXPORT uint8_t get_threshold(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const; + VSOMEIP_EXPORT void get_event_update_properties( + service_t _service, instance_t _instance, event_t _event, + std::chrono::milliseconds &_cycle, + bool &_change_resets_cycle, bool &_update_on_change_) const; + VSOMEIP_EXPORT std::uint32_t get_max_message_size_local() const; VSOMEIP_EXPORT std::uint32_t get_max_message_size_reliable(const std::string& _address, std::uint16_t _port) const; VSOMEIP_EXPORT std::uint32_t get_max_message_size_unreliable() const; VSOMEIP_EXPORT std::uint32_t get_buffer_shrink_threshold() const; - VSOMEIP_EXPORT bool supports_selective_broadcasts(boost::asio::ip::address _address) const; + VSOMEIP_EXPORT bool supports_selective_broadcasts(const boost::asio::ip::address &_address) const; VSOMEIP_EXPORT bool is_offered_remote(service_t _service, instance_t _instance) const; @@ -172,7 +186,8 @@ public: VSOMEIP_EXPORT std::uint32_t get_permissions_uds() const; VSOMEIP_EXPORT std::uint32_t get_permissions_shm() const; - VSOMEIP_EXPORT bool check_routing_credentials(client_t _client, uint32_t _uid, uint32_t _gid) const; + VSOMEIP_EXPORT bool check_routing_credentials(client_t _client, + const vsomeip_sec_client_t *_sec_client) const; VSOMEIP_EXPORT std::map> get_plugins( const std::string &_name) const; @@ -189,7 +204,8 @@ public: VSOMEIP_EXPORT ttl_map_t get_ttl_factor_offers() const; VSOMEIP_EXPORT ttl_map_t get_ttl_factor_subscribes() const; - VSOMEIP_EXPORT std::shared_ptr get_debounce( + VSOMEIP_EXPORT std::shared_ptr get_debounce( + const std::string &_name, service_t _service, instance_t _instance, event_t _event) const; VSOMEIP_EXPORT endpoint_queue_limit_t get_endpoint_queue_limit( @@ -222,15 +238,16 @@ public: VSOMEIP_EXPORT int get_udp_receive_buffer_size() const; - VSOMEIP_EXPORT bool has_overlay(const std::string &_name) const; - VSOMEIP_EXPORT void load_overlay(const std::string &_name); - - VSOMEIP_EXPORT bool tp_segment_messages_client_to_service( - service_t _service, std::string _ip_target, - std::uint16_t _port_target, method_t _method) const; - VSOMEIP_EXPORT bool tp_segment_messages_service_to_client( - service_t _service, std::string _ip_service, + VSOMEIP_EXPORT bool is_tp_client( + service_t _service, + const std::string &_address, std::uint16_t _port, + method_t _method) const; + VSOMEIP_EXPORT bool is_tp_service( + service_t _service, const std::string &_ip_service, std::uint16_t _port_service, method_t _method) const; + VSOMEIP_EXPORT void get_tp_configuration( + service_t _service, instance_t _instance, method_t _method, bool _is_client, + std::uint16_t &_max_segment_length, std::uint32_t &_separation_time) const; VSOMEIP_EXPORT std::uint32_t get_shutdown_timeout() const; @@ -244,19 +261,36 @@ public: VSOMEIP_EXPORT partition_id_t get_partition_id( service_t _service, instance_t _instance) const; + VSOMEIP_EXPORT std::map get_additional_data( + const std::string &_application_name, + const std::string &_plugin_name); + + VSOMEIP_EXPORT reliability_type_e get_reliability_type( + const boost::asio::ip::address &_reliable_address, + const uint16_t &_reliable_port, + const boost::asio::ip::address &_unreliable_address, + const uint16_t &_unreliable_port) const; + + VSOMEIP_EXPORT bool is_security_enabled() const; + VSOMEIP_EXPORT bool is_security_audit() const; + VSOMEIP_EXPORT bool is_remote_access_allowed() const; + private: void read_data(const std::set &_input, + std::vector &_elements, + std::set &_failed, + bool _mandatory_only, bool _read_second_level = false); +#ifndef VSOMEIP_DISABLE_POLICY + void load_policy_data(const std::string &_input, std::vector &_elements, std::set &_failed, bool _mandatory_only); - +#endif // !VSOMEIP_DISABLE_POLICY bool load_data(const std::vector &_elements, bool _load_mandatory, bool _load_optional); bool load_logging(const configuration_element &_element, std::set &_warnings); - bool load_routing(const configuration_element &_element); - bool load_routing_credentials(const configuration_element &_element); bool load_applications(const configuration_element &_element); void load_application_data(const boost::property_tree::ptree &_tree, @@ -264,7 +298,7 @@ private: std::map> load_plugins( const boost::property_tree::ptree &_tree, - const std::string& _application_name); + const std::string &_application_name); struct plugin_config_data_t { std::string name_; @@ -275,6 +309,15 @@ private: const plugin_config_data_t &_plugin_data, const std::string& _application_name); + bool load_routing(const configuration_element &_element); + bool load_routing_host(const boost::property_tree::ptree &_tree, + const std::string &_name); + bool load_routing_guests(const boost::property_tree::ptree &_tree); + void load_routing_guest_ports(const boost::property_tree::ptree &_tree); + + bool load_routing_credentials(const configuration_element &_element); // compatibility + void load_routing_client_ports(const configuration_element &_element); // compatibility + void load_tracing(const configuration_element &_element); void load_trace_channels(const boost::property_tree::ptree &_tree); void load_trace_channel(const boost::property_tree::ptree &_tree); @@ -327,11 +370,12 @@ private: void load_selective_broadcasts_support(const configuration_element &_element); void load_debounce(const configuration_element &_element); - void load_service_debounce(const boost::property_tree::ptree &_tree); + void load_service_debounce(const boost::property_tree::ptree &_tree, + debounce_configuration_t &_debounces); void load_events_debounce(const boost::property_tree::ptree &_tree, - std::map> &_debounces); + std::map > &_debounces); void load_event_debounce(const boost::property_tree::ptree &_tree, - std::map> &_debounces); + std::map > &_debounces); void load_event_debounce_ignore(const boost::property_tree::ptree &_tree, std::map &_ignore); void load_acceptances(const configuration_element &_element); @@ -354,8 +398,8 @@ private: instance_t _instance) const; std::shared_ptr find_service(service_t _service, instance_t _instance) const; std::shared_ptr find_service_unlocked(service_t _service, instance_t _instance) const; - service * find_service_by_ip_port(service_t _service, const std::string& _ip, - std::uint16_t _port) const; + std::shared_ptr find_service(service_t _service, + const std::string &_address, std::uint16_t _port) const; std::shared_ptr find_eventgroup(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const; bool find_port(uint16_t &_port, uint16_t _remote, bool _reliable, @@ -396,7 +440,6 @@ private: const std::string default_unicast_; bool is_loaded_; bool is_logging_loaded_; - bool is_overlay_; std::set mandatory_; @@ -404,6 +447,7 @@ protected: // Configuration data boost::asio::ip::address unicast_; boost::asio::ip::address netmask_; + unsigned short prefix_; std::string device_; diagnosis_t diagnosis_; diagnosis_t diagnosis_mask_; @@ -414,23 +458,9 @@ protected: std::string logfile_; vsomeip_v3::logger::level_e loglevel_; - std::map - >, // plugins - int, // nice level - std::string // overlay -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG - , bool // has session handling? -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG - > + std::map< + std::string, + application_configuration > applications_; std::set client_identifiers_; @@ -446,7 +476,7 @@ protected: std::list< std::shared_ptr > clients_; - std::string routing_host_; + routing_t routing_; bool is_sd_enabled_; std::string sd_protocol_; @@ -523,11 +553,12 @@ protected: ET_NPDU_DEFAULT_TIMINGS, ET_PLUGIN_NAME, ET_PLUGIN_TYPE, - ET_ROUTING_CREDENTIALS, ET_SHUTDOWN_TIMEOUT, ET_MAX_REMOTE_SUBSCRIBERS, ET_PARTITIONS, - ET_MAX = 44 + ET_SECURITY_AUDIT_MODE, + ET_SECURITY_REMOTE_ACCESS, + ET_MAX = 45 }; bool is_configured_[ET_MAX]; @@ -549,7 +580,7 @@ protected: ttl_map_t ttl_factors_offers_; ttl_map_t ttl_factors_subscriptions_; - std::map>>> debounces_; + debounce_configuration_t debounces_; std::map> endpoint_queue_limits_; endpoint_queue_limit_t endpoint_queue_limit_external_; @@ -581,6 +612,7 @@ protected: uint32_t statistics_interval_; uint32_t statistics_min_freq_; uint32_t statistics_max_messages_; + uint8_t max_remote_subscribers_; mutable std::mutex partitions_mutex_; @@ -589,6 +621,20 @@ protected: partition_id_t > > partitions_; + + std::string path_; + + std::map + > + > plugins_additional_; + + bool is_security_enabled_; + bool is_security_audit_; + bool is_remote_access_allowed_; }; } // namespace cfg diff --git a/implementation/configuration/include/configuration_plugin.hpp b/implementation/configuration/include/configuration_plugin.hpp index 583c3d8..3ffc968 100644 --- a/implementation/configuration/include/configuration_plugin.hpp +++ b/implementation/configuration/include/configuration_plugin.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -17,13 +17,9 @@ class configuration; class configuration_plugin { public: - virtual ~configuration_plugin() -#ifndef ANDROID - {} -#else - ; -#endif - virtual std::shared_ptr get_configuration(const std::string &_name) = 0; + virtual ~configuration_plugin() = default; + virtual std::shared_ptr get_configuration( + const std::string &_name, const std::string &_path) = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/configuration/include/configuration_plugin_impl.hpp b/implementation/configuration/include/configuration_plugin_impl.hpp index fd95628..3fcfbef 100644 --- a/implementation/configuration/include/configuration_plugin_impl.hpp +++ b/implementation/configuration/include/configuration_plugin_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -27,14 +27,15 @@ public: configuration_plugin_impl(); virtual ~configuration_plugin_impl(); - std::shared_ptr get_configuration(const std::string &_name); + std::shared_ptr get_configuration(const std::string &_name, + const std::string &_path); private: std::mutex mutex_; std::shared_ptr default_; -#ifdef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS +#if 0 std::map > configurations_; -#endif // VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS +#endif }; } // namespace vsomeip_v3 diff --git a/implementation/configuration/include/debounce.hpp b/implementation/configuration/include/debounce.hpp index dc61514..30ad984 100644 --- a/implementation/configuration/include/debounce.hpp +++ b/implementation/configuration/include/debounce.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2017-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -21,7 +21,7 @@ namespace cfg { struct debounce { debounce() : on_change_(false), on_change_resets_interval_(false), - interval_(0), + interval_(-1), // aka "never" last_forwarded_((std::chrono::steady_clock::time_point::max)()) { } diff --git a/implementation/configuration/include/e2e.hpp b/implementation/configuration/include/e2e.hpp index 705c92d..8345c2a 100644 --- a/implementation/configuration/include/e2e.hpp +++ b/implementation/configuration/include/e2e.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -16,7 +16,7 @@ namespace vsomeip_v3 { namespace cfg { struct e2e { - typedef std::map custom_parameters_t; + using custom_parameters_t = std::map>; e2e() : variant(""), @@ -25,7 +25,7 @@ struct e2e { event_id(0) { } - e2e(std::string _variant, std::string _profile, service_t _service_id, + e2e(const std::string &_variant, const std::string &_profile, service_t _service_id, event_t _event_id, custom_parameters_t&& _custom_parameters) : variant(_variant), profile(_profile), diff --git a/implementation/configuration/include/event.hpp b/implementation/configuration/include/event.hpp index 84dc5a0..1e35a85 100644 --- a/implementation/configuration/include/event.hpp +++ b/implementation/configuration/include/event.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -17,18 +17,25 @@ namespace cfg { struct eventgroup; struct event { - event(event_t _id) + event(event_t _id, bool _is_field, reliability_type_e _reliability, + std::chrono::milliseconds _cycle, bool _change_resets_cycle, + bool _update_on_change) : id_(_id), - is_placeholder_(true), - is_field_(false), - reliability_(reliability_type_e::RT_UNRELIABLE) { + is_field_(_is_field), + reliability_(_reliability), + cycle_(_cycle), + change_resets_cycle_(_change_resets_cycle), + update_on_change_(_update_on_change) { } event_t id_; - bool is_placeholder_; bool is_field_; reliability_type_e reliability_; std::vector > groups_; + + std::chrono::milliseconds cycle_; + bool change_resets_cycle_; + bool update_on_change_; }; } // namespace cfg diff --git a/implementation/configuration/include/eventgroup.hpp b/implementation/configuration/include/eventgroup.hpp index 1402b51..328a02d 100644 --- a/implementation/configuration/include/eventgroup.hpp +++ b/implementation/configuration/include/eventgroup.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/configuration/include/internal.hpp.in b/implementation/configuration/include/internal.hpp.in index efd9ba0..91cd1ee 100644 --- a/implementation/configuration/include/internal.hpp.in +++ b/implementation/configuration/include/internal.hpp.in @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,7 +8,10 @@ #include #include +#include + #include +#include #define VSOMEIP_ENV_APPLICATION_NAME "VSOMEIP_APPLICATION_NAME" #define VSOMEIP_ENV_CONFIGURATION "VSOMEIP_CONFIGURATION" @@ -20,7 +23,7 @@ #define VSOMEIP_DEFAULT_CONFIGURATION_FILE "@DEFAULT_CONFIGURATION_FILE@" #define VSOMEIP_LOCAL_CONFIGURATION_FILE "./vsomeip.json" -#define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_plc.json,vsomeip_log.json,vsomeip_security.json,vsomeip_whitelist.json" +#define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_events.json,vsomeip_plc.json,vsomeip_log.json,vsomeip_security.json,vsomeip_whitelist.json,vsomeip_policy_extensions.json" #define VSOMEIP_DEFAULT_CONFIGURATION_FOLDER "@DEFAULT_CONFIGURATION_FOLDER@" #define VSOMEIP_DEBUG_CONFIGURATION_FOLDER "/var/opt/public/sin/vsomeip/" @@ -28,6 +31,8 @@ #define VSOMEIP_BASE_PATH "@VSOMEIP_BASE_PATH@/" +#define VSOMEIP_ROUTING_HOST_PORT_DEFAULT 31490 + #ifdef _WIN32 #define VSOMEIP_CFG_LIBRARY "vsomeip3-cfg.dll" #else @@ -46,6 +51,12 @@ #define VSOMEIP_E2E_LIBRARY "libvsomeip3-e2e.so.@VSOMEIP_MAJOR_VERSION@" #endif +#ifdef _WIN32 +#define VSOMEIP_SEC_LIBRARY "vsomeip3-sec.dll" +#else +#define VSOMEIP_SEC_LIBRARY "libvsomeip3-sec.so" +#endif + #define VSOMEIP_ROUTING_CLIENT 0 #define VSOMEIP_CLIENT_UNSET 0xFFFF @@ -57,9 +68,11 @@ #define VSOMEIP_UNICAST_ADDRESS "@VSOMEIP_UNICAST_ADDRESS@" #define VSOMEIP_NETMASK "255.255.255.0" +#define VSOMEIP_PREFIX 24 #define VSOMEIP_DEFAULT_CONNECT_TIMEOUT 100 #define VSOMEIP_MAX_CONNECT_TIMEOUT 1600 +#define VSOMEIP_DEFAULT_CONNECTING_TIMEOUT 100 #define VSOMEIP_DEFAULT_FLUSH_TIMEOUT 1000 #define VSOMEIP_DEFAULT_SHUTDOWN_TIMEOUT 5000 @@ -70,6 +83,8 @@ #define VSOMEIP_MAX_TCP_RESTART_ABORTS 5 #define VSOMEIP_MAX_TCP_SENT_WAIT_TIME 10000 +#define VSOMEIP_TP_MAX_SEGMENT_LENGTH_DEFAULT 1392 + #define VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD 5 #define VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT 5000 @@ -92,93 +107,12 @@ #define VSOMEIP_MAX_WAIT_SENT 5 -#define VSOMEIP_COMMAND_HEADER_SIZE 7 - -#define VSOMEIP_COMMAND_TYPE_POS 0 -#define VSOMEIP_COMMAND_CLIENT_POS 1 -#define VSOMEIP_COMMAND_SIZE_POS_MIN 3 -#define VSOMEIP_COMMAND_SIZE_POS_MAX 6 -#define VSOMEIP_COMMAND_PAYLOAD_POS 7 - -#define VSOMEIP_ASSIGN_CLIENT 0x00 -#define VSOMEIP_ASSIGN_CLIENT_ACK 0x01 -#define VSOMEIP_REGISTER_APPLICATION 0x02 -#define VSOMEIP_DEREGISTER_APPLICATION 0x03 -#define VSOMEIP_APPLICATION_LOST 0x04 -#define VSOMEIP_ROUTING_INFO 0x05 -#define VSOMEIP_REGISTERED_ACK 0x06 - -#define VSOMEIP_PING 0x0E -#define VSOMEIP_PONG 0x0F - -#define VSOMEIP_OFFER_SERVICE 0x10 -#define VSOMEIP_STOP_OFFER_SERVICE 0x11 -#define VSOMEIP_SUBSCRIBE 0x12 -#define VSOMEIP_UNSUBSCRIBE 0x13 -#define VSOMEIP_REQUEST_SERVICE 0x14 -#define VSOMEIP_RELEASE_SERVICE 0x15 -#define VSOMEIP_SUBSCRIBE_NACK 0x16 -#define VSOMEIP_SUBSCRIBE_ACK 0x17 - -#define VSOMEIP_SEND 0x18 -#define VSOMEIP_NOTIFY 0x19 -#define VSOMEIP_NOTIFY_ONE 0x1A - -#define VSOMEIP_REGISTER_EVENT 0x1B -#define VSOMEIP_UNREGISTER_EVENT 0x1C -#define VSOMEIP_ID_RESPONSE 0x1D -#define VSOMEIP_ID_REQUEST 0x1E -#define VSOMEIP_OFFERED_SERVICES_REQUEST 0x1F -#define VSOMEIP_OFFERED_SERVICES_RESPONSE 0x20 -#define VSOMEIP_UNSUBSCRIBE_ACK 0x21 -#define VSOMEIP_RESEND_PROVIDED_EVENTS 0x22 - -#define VSOMEIP_UPDATE_SECURITY_POLICY 0x23 -#define VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE 0x24 -#define VSOMEIP_REMOVE_SECURITY_POLICY 0x25 -#define VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE 0x26 -#define VSOMEIP_UPDATE_SECURITY_CREDENTIALS 0x27 -#define VSOMEIP_DISTRIBUTE_SECURITY_POLICIES 0x28 -#define VSOMEIP_UPDATE_SECURITY_POLICY_INT 0x29 -#define VSOMEIP_EXPIRED_SUBSCRIPTION 0x2A - -#define VSOMEIP_SUSPEND 0x30 - -#define VSOMEIP_SEND_COMMAND_SIZE 13 -#define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN 7 -#define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MAX 8 -#define VSOMEIP_SEND_COMMAND_RELIABLE_POS 9 -#define VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS 10 -#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN 11 -#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MAX 12 -#define VSOMEIP_SEND_COMMAND_PAYLOAD_POS 13 - -#define VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE 9 -#define VSOMEIP_OFFER_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE 11 -#define VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_SUBSCRIBE_COMMAND_SIZE 18 -#define VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE 19 -#define VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE 19 -#define VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE 17 -#define VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE 15 -#define VSOMEIP_REGISTER_EVENT_COMMAND_SIZE 16 -#define VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE 14 -#define VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE 8 -#define VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE 11 -#define VSOMEIP_REMOVE_SECURITY_POLICY_COMMAND_SIZE 19 -#define VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE 11 -#define VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE 11 -#define VSOMEIP_PING_COMMAND_SIZE 7 -#define VSOMEIP_PONG_COMMAND_SIZE 7 -#define VSOMEIP_REGISTER_APPLICATION_COMMAND_SIZE 7 -#define VSOMEIP_DEREGISTER_APPLICATION_COMMAND_SIZE 7 -#define VSOMEIP_REGISTERED_ACK_COMMAND_SIZE 7 -#define VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE 17 - - -#ifndef _WIN32 +#define VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE 19 + +#define VSOMEIP_MINIMUM_CHECK_TTL_TIMEOUT 100 +#define VSOMEIP_SETSOCKOPT_TIMEOUT_US 500000 // microseconds + +#if defined(__linux__) || defined(ANDROID) #include #endif @@ -192,31 +126,11 @@ namespace vsomeip_v3 { -typedef enum { - RIE_ADD_CLIENT = 0x0, - RIE_ADD_SERVICE_INSTANCE = 0x1, - RIE_DEL_SERVICE_INSTANCE = 0x2, - RIE_DEL_CLIENT = 0x3, -} routing_info_entry_e; - -struct service_data_t { - service_t service_; - instance_t instance_; - major_version_t major_; - minor_version_t minor_; - - bool operator<(const service_data_t &_other) const { - return (service_ < _other.service_ - || (service_ == _other.service_ - && instance_ < _other.instance_)); - } -}; - -typedef enum { +enum class subscription_state_e { SUBSCRIPTION_ACKNOWLEDGED, SUBSCRIPTION_NOT_ACKNOWLEDGED, IS_SUBSCRIBING -} subscription_state_e; +}; const std::uint32_t MESSAGE_SIZE_UNLIMITED = (std::numeric_limits::max)(); @@ -230,8 +144,6 @@ const std::uint32_t MAX_RECONNECTS_UNLIMITED = (std::numeric_limits credentials_t; - enum class port_type_e { PT_OPTIONAL, PT_SECURE, @@ -239,7 +151,11 @@ enum class port_type_e { PT_UNKNOWN }; -typedef uint8_t partition_id_t; +using debounce_configuration_t = + std::map>>>; + +using partition_id_t = std::uint8_t; const partition_id_t VSOMEIP_DEFAULT_PARTITION_ID = 0; } // namespace vsomeip_v3 diff --git a/implementation/configuration/include/internal_android.hpp b/implementation/configuration/include/internal_android.hpp index 8ecd2b5..1efa0fa 100644 --- a/implementation/configuration/include/internal_android.hpp +++ b/implementation/configuration/include/internal_android.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,7 +8,10 @@ #include #include +#include + #include +#include #define VSOMEIP_ENV_APPLICATION_NAME "VSOMEIP_APPLICATION_NAME" #define VSOMEIP_ENV_CONFIGURATION "VSOMEIP_CONFIGURATION" @@ -17,33 +20,41 @@ #define VSOMEIP_ENV_MANDATORY_CONFIGURATION_FILES "VSOMEIP_MANDATORY_CONFIGURATION_FILES" #define VSOMEIP_ENV_LOAD_PLUGINS "VSOMEIP_LOAD_PLUGINS" #define VSOMEIP_ENV_CLIENTSIDELOGGING "VSOMEIP_CLIENTSIDELOGGING" -#define VSOMEIP_ENV_BASE_PATH "VSOMEIP_BASE_PATH" -#define VSOMEIP_DEFAULT_CONFIGURATION_FILE "/vendor/etc/vsomeip.json" +#define VSOMEIP_DEFAULT_CONFIGURATION_FILE "/vendor/run/etc/vsomeip.json" #define VSOMEIP_LOCAL_CONFIGURATION_FILE "./vsomeip.json" -#define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_plc.json,vsomeip_log.json,vsomeip_security.json,vsomeip_whitelist.json" +#define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_plc.json,vsomeip_log.json,vsomeip_security.json,vsomeip_whitelist.json,vsomeip_policy_extensions.json" -#define VSOMEIP_DEFAULT_CONFIGURATION_FOLDER "/vendor/etc/vsomeip" +#define VSOMEIP_DEFAULT_CONFIGURATION_FOLDER "/vendor/run/etc/vsomeip" #define VSOMEIP_DEBUG_CONFIGURATION_FOLDER "/var/opt/public/sin/vsomeip/" #define VSOMEIP_LOCAL_CONFIGURATION_FOLDER "./vsomeip" -#define VSOMEIP_BASE_PATH "/storage/" +// VSOMEIP_BASE_PATH should be specified in Android.bp or/and Android.mk file via c/c++ compiler flags. +// #define VSOMEIP_BASE_PATH "/storage/" + +#define VSOMEIP_ROUTING_HOST_PORT_DEFAULT 31490 + +#define VSOMEIP_CFG_LIBRARY "libvsomeip_cfg.so" -#define VSOMEIP_CFG_LIBRARY "libvsomeip3-cfg.so" +#define VSOMEIP_SD_LIBRARY "libvsomeip_sd.so" -#define VSOMEIP_SD_LIBRARY "libvsomeip3-sd.so" +#define VSOMEIP_E2E_LIBRARY "libvsomeip_e2e.so" -#define VSOMEIP_E2E_LIBRARY "libvsomeip3-e2e.so" +#define VSOMEIP_SEC_LIBRARY "libvsomeip_sec.so" +#define VSOMEIP_ROUTING "vsomeipd" #define VSOMEIP_ROUTING_CLIENT 0 +#define VSOMEIP_ROUTING_INFO_SIZE_INIT 256 #define VSOMEIP_CLIENT_UNSET 0xFFFF #define VSOMEIP_UNICAST_ADDRESS "127.0.0.1" #define VSOMEIP_NETMASK "255.255.255.0" +#define VSOMEIP_PREFIX 24 #define VSOMEIP_DEFAULT_CONNECT_TIMEOUT 100 #define VSOMEIP_MAX_CONNECT_TIMEOUT 1600 +#define VSOMEIP_DEFAULT_CONNECTING_TIMEOUT 100 #define VSOMEIP_DEFAULT_FLUSH_TIMEOUT 1000 #define VSOMEIP_DEFAULT_SHUTDOWN_TIMEOUT 5000 @@ -54,6 +65,8 @@ #define VSOMEIP_MAX_TCP_RESTART_ABORTS 5 #define VSOMEIP_MAX_TCP_SENT_WAIT_TIME 10000 +#define VSOMEIP_TP_MAX_SEGMENT_LENGTH_DEFAULT 1392 + #define VSOMEIP_DEFAULT_BUFFER_SHRINK_THRESHOLD 5 #define VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT 5000 @@ -76,90 +89,10 @@ #define VSOMEIP_MAX_WAIT_SENT 5 -#define VSOMEIP_COMMAND_HEADER_SIZE 7 - -#define VSOMEIP_COMMAND_TYPE_POS 0 -#define VSOMEIP_COMMAND_CLIENT_POS 1 -#define VSOMEIP_COMMAND_SIZE_POS_MIN 3 -#define VSOMEIP_COMMAND_SIZE_POS_MAX 6 -#define VSOMEIP_COMMAND_PAYLOAD_POS 7 - -#define VSOMEIP_ASSIGN_CLIENT 0x00 -#define VSOMEIP_ASSIGN_CLIENT_ACK 0x01 -#define VSOMEIP_REGISTER_APPLICATION 0x02 -#define VSOMEIP_DEREGISTER_APPLICATION 0x03 -#define VSOMEIP_APPLICATION_LOST 0x04 -#define VSOMEIP_ROUTING_INFO 0x05 -#define VSOMEIP_REGISTERED_ACK 0x06 - -#define VSOMEIP_PING 0x0E -#define VSOMEIP_PONG 0x0F - -#define VSOMEIP_OFFER_SERVICE 0x10 -#define VSOMEIP_STOP_OFFER_SERVICE 0x11 -#define VSOMEIP_SUBSCRIBE 0x12 -#define VSOMEIP_UNSUBSCRIBE 0x13 -#define VSOMEIP_REQUEST_SERVICE 0x14 -#define VSOMEIP_RELEASE_SERVICE 0x15 -#define VSOMEIP_SUBSCRIBE_NACK 0x16 -#define VSOMEIP_SUBSCRIBE_ACK 0x17 - -#define VSOMEIP_SEND 0x18 -#define VSOMEIP_NOTIFY 0x19 -#define VSOMEIP_NOTIFY_ONE 0x1A - -#define VSOMEIP_REGISTER_EVENT 0x1B -#define VSOMEIP_UNREGISTER_EVENT 0x1C -#define VSOMEIP_ID_RESPONSE 0x1D -#define VSOMEIP_ID_REQUEST 0x1E -#define VSOMEIP_OFFERED_SERVICES_REQUEST 0x1F -#define VSOMEIP_OFFERED_SERVICES_RESPONSE 0x20 -#define VSOMEIP_UNSUBSCRIBE_ACK 0x21 -#define VSOMEIP_RESEND_PROVIDED_EVENTS 0x22 - -#define VSOMEIP_UPDATE_SECURITY_POLICY 0x23 -#define VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE 0x24 -#define VSOMEIP_REMOVE_SECURITY_POLICY 0x25 -#define VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE 0x26 -#define VSOMEIP_UPDATE_SECURITY_CREDENTIALS 0x27 -#define VSOMEIP_DISTRIBUTE_SECURITY_POLICIES 0x28 -#define VSOMEIP_UPDATE_SECURITY_POLICY_INT 0x29 -#define VSOMEIP_EXPIRED_SUBSCRIPTION 0x2A - -#define VSOMEIP_SUSPEND 0x30 - -#define VSOMEIP_SEND_COMMAND_SIZE 13 -#define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN 7 -#define VSOMEIP_SEND_COMMAND_INSTANCE_POS_MAX 8 -#define VSOMEIP_SEND_COMMAND_RELIABLE_POS 9 -#define VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS 10 -#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN 11 -#define VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MAX 12 -#define VSOMEIP_SEND_COMMAND_PAYLOAD_POS 13 - -#define VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE 9 -#define VSOMEIP_OFFER_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE 11 -#define VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE 16 -#define VSOMEIP_SUBSCRIBE_COMMAND_SIZE 18 -#define VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE 19 -#define VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE 19 -#define VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE 17 -#define VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE 15 -#define VSOMEIP_REGISTER_EVENT_COMMAND_SIZE 16 -#define VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE 14 -#define VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE 8 -#define VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE 11 -#define VSOMEIP_REMOVE_SECURITY_POLICY_COMMAND_SIZE 19 -#define VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE 11 -#define VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE 11 -#define VSOMEIP_PING_COMMAND_SIZE 7 -#define VSOMEIP_PONG_COMMAND_SIZE 7 -#define VSOMEIP_REGISTER_APPLICATION_COMMAND_SIZE 7 -#define VSOMEIP_DEREGISTER_APPLICATION_COMMAND_SIZE 7 -#define VSOMEIP_REGISTERED_ACK_COMMAND_SIZE 7 -#define VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE 17 +#define VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE 19 + +#define VSOMEIP_MINIMUM_CHECK_TTL_TIMEOUT 100 +#define VSOMEIP_SETSOCKOPT_TIMEOUT_US 500000 // microseconds #include @@ -180,19 +113,6 @@ typedef enum { RIE_DEL_CLIENT = 0x3, } routing_info_entry_e; -struct service_data_t { - service_t service_; - instance_t instance_; - major_version_t major_; - minor_version_t minor_; - - bool operator<(const service_data_t &_other) const { - return (service_ < _other.service_ - || (service_ == _other.service_ - && instance_ < _other.instance_)); - } -}; - typedef enum { SUBSCRIPTION_ACKNOWLEDGED, SUBSCRIPTION_NOT_ACKNOWLEDGED, @@ -211,8 +131,6 @@ const std::uint32_t MAX_RECONNECTS_UNLIMITED = (std::numeric_limits credentials_t; - enum class port_type_e { PT_OPTIONAL, PT_SECURE, @@ -220,6 +138,14 @@ enum class port_type_e { PT_UNKNOWN }; +typedef std::map + > + > +> debounce_configuration_t; + typedef uint8_t partition_id_t; const partition_id_t VSOMEIP_DEFAULT_PARTITION_ID = 0; diff --git a/implementation/configuration/include/routing.hpp b/implementation/configuration/include/routing.hpp new file mode 100644 index 0000000..4ffc3b9 --- /dev/null +++ b/implementation/configuration/include/routing.hpp @@ -0,0 +1,71 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_CFG_ROUTING_HPP_ +#define VSOMEIP_V3_CFG_ROUTING_HPP_ + +#include + +#include +#include + +#ifdef ANDROID +#include "internal_android.hpp" +#else +#include "internal.hpp" +#endif + +namespace vsomeip_v3 { +namespace cfg { + +struct routing_host_t { + std::string name_; + boost::asio::ip::address unicast_; + port_t port_; + + routing_host_t() : port_(VSOMEIP_ROUTING_HOST_PORT_DEFAULT) {} + + routing_host_t &operator=(const routing_host_t &_other) { + name_ = _other.name_; + unicast_ = _other.unicast_; + port_ = _other.port_; + + return (*this); + } +}; + +struct routing_guests_t { + boost::asio::ip::address unicast_; + std::set > ports_; + + routing_guests_t &operator=(const routing_guests_t &_other) { + unicast_ = _other.unicast_; + ports_ = _other.ports_; + + return (*this); + } +}; + +struct routing_t { + bool is_enabled_; + + routing_host_t host_; + routing_guests_t guests_; + + routing_t() : is_enabled_(true) {} + + routing_t &operator=(const routing_t &_other) { + is_enabled_ = _other.is_enabled_; + host_ = _other.host_; + guests_ = _other.guests_; + + return (*this); + } +}; + +} // namespace cfg +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_CFG_ROUTING_HPP_ diff --git a/implementation/configuration/include/service.hpp b/implementation/configuration/include/service.hpp index 8077f8e..af84880 100644 --- a/implementation/configuration/include/service.hpp +++ b/implementation/configuration/include/service.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -25,10 +25,6 @@ struct service { uint16_t reliable_; uint16_t unreliable_; - major_version_t major_; - minor_version_t minor_; - ttl_t ttl_; - std::string multicast_address_; uint16_t multicast_port_; @@ -36,17 +32,16 @@ struct service { // [0] = debounce_time // [1] = retention_time - typedef std::map> npdu_time_configuration_t; + using npdu_time_configuration_t = std::map>; npdu_time_configuration_t debounce_times_requests_; npdu_time_configuration_t debounce_times_responses_; - std::shared_ptr group_; std::map > events_; std::map > eventgroups_; // SOME/IP-TP - std::set tp_segment_messages_client_to_service_; - std::set tp_segment_messages_service_to_client_; + std::map > tp_client_config_; + std::map > tp_service_config_; }; } // namespace cfg diff --git a/implementation/configuration/include/service_instance_range.hpp b/implementation/configuration/include/service_instance_range.hpp index a585d7a..9ae162f 100644 --- a/implementation/configuration/include/service_instance_range.hpp +++ b/implementation/configuration/include/service_instance_range.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/configuration/include/trace.hpp b/implementation/configuration/include/trace.hpp index c9eb8cb..a83aa81 100644 --- a/implementation/configuration/include/trace.hpp +++ b/implementation/configuration/include/trace.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,6 +11,7 @@ #include #include +#include "../../tracing/include/enumeration_types.hpp" namespace vsomeip_v3 { namespace cfg { @@ -22,12 +23,12 @@ struct trace_channel { struct trace_filter { trace_filter() - : is_positive_(true), + : ftype_(vsomeip_v3::trace::filter_type_e::POSITIVE), is_range_(false) { } std::vector channels_; - bool is_positive_; + vsomeip_v3::trace::filter_type_e ftype_; bool is_range_; std::vector matches_; }; diff --git a/implementation/configuration/include/watchdog.hpp b/implementation/configuration/include/watchdog.hpp index 9fe81ff..5c9de1c 100644 --- a/implementation/configuration/include/watchdog.hpp +++ b/implementation/configuration/include/watchdog.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp index 6fdbb67..2a8f632 100644 --- a/implementation/configuration/src/configuration_impl.cpp +++ b/implementation/configuration/src/configuration_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,22 +6,25 @@ #include #include #include +#include #include #include -#include #include #define WIN32_LEAN_AND_MEAN +#define BOOST_BIND_GLOBAL_PLACEHOLDERS #include #include #include +#include #include #include #include #include #include +#include #include "../include/client.hpp" #include "../include/configuration_impl.hpp" @@ -29,20 +32,22 @@ #include "../include/eventgroup.hpp" #include "../include/service.hpp" #include "../../logger/include/logger_impl.hpp" +#include "../../protocol/include/protocol.hpp" #include "../../routing/include/event.hpp" #include "../../service_discovery/include/defines.hpp" #include "../../utility/include/utility.hpp" #include "../../plugin/include/plugin_manager.hpp" +#include "../../security/include/policy_manager_impl.hpp" #include "../../security/include/security.hpp" namespace vsomeip_v3 { namespace cfg { -configuration_impl::configuration_impl() +configuration_impl::configuration_impl(const std::string &_path) : default_unicast_("local"), is_loaded_(false), is_logging_loaded_(false), - is_overlay_(false), + prefix_(VSOMEIP_PREFIX), diagnosis_(VSOMEIP_DIAGNOSIS_ADDRESS), diagnosis_mask_(0xFF00), has_console_log_(true), @@ -95,7 +100,12 @@ configuration_impl::configuration_impl() statistics_interval_(VSOMEIP_DEFAULT_STATISTICS_INTERVAL), statistics_min_freq_(VSOMEIP_DEFAULT_STATISTICS_MIN_FREQ), statistics_max_messages_(VSOMEIP_DEFAULT_STATISTICS_MAX_MSG), - max_remote_subscribers_(VSOMEIP_DEFAULT_MAX_REMOTE_SUBSCRIBERS) { + max_remote_subscribers_(VSOMEIP_DEFAULT_MAX_REMOTE_SUBSCRIBERS), + path_(_path), + is_security_enabled_(false), + is_security_audit_(false), + is_remote_access_allowed_(true) { + unicast_ = unicast_.from_string(VSOMEIP_UNICAST_ADDRESS); netmask_ = netmask_.from_string(VSOMEIP_NETMASK); for (auto i = 0; i < ET_MAX; i++) @@ -107,7 +117,6 @@ configuration_impl::configuration_impl(const configuration_impl &_other) default_unicast_(_other.default_unicast_), is_loaded_(_other.is_loaded_), is_logging_loaded_(_other.is_logging_loaded_), - is_overlay_(_other.is_overlay_), mandatory_(_other.mandatory_), max_configured_message_size_(_other.max_configured_message_size_), max_local_message_size_(_other.max_local_message_size_), @@ -125,7 +134,8 @@ configuration_impl::configuration_impl(const configuration_impl &_other) npdu_default_debounce_resp_(_other.npdu_default_debounce_resp_), npdu_default_max_retention_requ_(_other.npdu_default_max_retention_requ_), npdu_default_max_retention_resp_(_other.npdu_default_max_retention_resp_), - shutdown_timeout_(_other.shutdown_timeout_) { + shutdown_timeout_(_other.shutdown_timeout_), + path_(_other.path_) { applications_.insert(_other.applications_.begin(), _other.applications_.end()); client_identifiers_ = _other.client_identifiers_; @@ -145,7 +155,7 @@ configuration_impl::configuration_impl(const configuration_impl &_other) loglevel_ = _other.loglevel_; - routing_host_ = _other.routing_host_; + routing_ = _other.routing_; is_sd_enabled_ = _other.is_sd_enabled_; sd_multicast_ = _other.sd_multicast_; @@ -201,6 +211,10 @@ configuration_impl::configuration_impl(const configuration_impl &_other) statistics_min_freq_ = _other.statistics_min_freq_; statistics_max_messages_ = _other.statistics_max_messages_; max_remote_subscribers_ = _other.max_remote_subscribers_; + + is_security_enabled_ = _other.is_security_enabled_; + is_security_audit_ = _other.is_security_audit_; + is_remote_access_allowed_ = _other.is_remote_access_allowed_; } configuration_impl::~configuration_impl() { @@ -211,10 +225,23 @@ bool configuration_impl::load(const std::string &_name) { if (is_loaded_) return true; + // Environment + char *its_env; + // Predefine file / folder std::string its_file(VSOMEIP_DEFAULT_CONFIGURATION_FILE); // configuration file std::string its_folder(VSOMEIP_DEFAULT_CONFIGURATION_FOLDER); // configuration folder + if (!path_.empty()) { + if (utility::is_file(path_)) { + its_file = path_; + its_folder = ""; + } else { + its_file = ""; + its_folder = path_; + } + } + // Override with local file / folder (if existing) std::string its_local_file(VSOMEIP_LOCAL_CONFIGURATION_FILE); if (utility::is_file(its_local_file)) { @@ -227,7 +254,12 @@ bool configuration_impl::load(const std::string &_name) { } // Override with path from environment (if existing) - const char *its_env = getenv(VSOMEIP_ENV_CONFIGURATION); + std::string its_named_configuration(VSOMEIP_ENV_CONFIGURATION); + its_named_configuration += "_" + _name; + + its_env = getenv(its_named_configuration.c_str()); + if (nullptr == its_env) + its_env = getenv(VSOMEIP_ENV_CONFIGURATION); if (nullptr != its_env) { if (utility::is_file(its_env)) { its_file = its_env; @@ -244,7 +276,7 @@ bool configuration_impl::load(const std::string &_name) { } if (its_folder != "") { its_input.insert(its_folder); -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) // load security configuration files from UID_GID sub folder if existing std::stringstream its_security_config_folder; its_security_config_folder << its_folder << "/" << getuid() << "_" << getgid(); @@ -280,8 +312,8 @@ bool configuration_impl::load(const std::string &_name) { // If the configuration is incomplete, this is the routing manager configuration or // the routing is yet unknown, read the full set of configuration files if (its_mandatory_elements.empty() || - _name == get_routing_host() || - "" == get_routing_host()) { + _name == get_routing_host_name() || + "" == get_routing_host_name()) { read_data(its_input, its_optional_elements, its_failed, false); load_data(its_mandatory_elements, false, true); load_data(its_optional_elements, true, true); @@ -297,9 +329,6 @@ bool configuration_impl::load(const std::string &_name) { set_magic_cookies_unicast_address(); std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now(); - VSOMEIP_INFO << "Parsed vsomeip configuration in " - << std::chrono::duration_cast(end - begin).count() - << "ms"; for (auto i : its_input) { if (utility::is_file(i)) @@ -309,16 +338,56 @@ bool configuration_impl::load(const std::string &_name) { VSOMEIP_INFO << "Using configuration folder: \"" << i << "\"."; } - is_loaded_ = true; + VSOMEIP_INFO << "Parsed vsomeip configuration in " + << std::chrono::duration_cast(end - begin).count() + << "ms"; + is_loaded_ = true; return is_loaded_; } +#ifndef VSOMEIP_DISABLE_SECURITY +bool configuration_impl::lazy_load_security(const std::string &_client_host) { + bool result(false); + + std::string its_folder = policy_manager_impl::get()->get_policy_extension_path(_client_host); + if (!its_folder.empty()) { + std::set its_input; + std::set its_failed; + std::vector its_mandatory_elements; + + its_input.insert(its_folder); + // load security configuration files from UID_GID sub folder if existing + std::string its_security_config_folder = policy_manager_impl::get()->get_security_config_folder(its_folder); + + if (!its_security_config_folder.empty()) + its_input.insert(its_security_config_folder); + + read_data(its_input, its_mandatory_elements, its_failed, true, true); + + for (const auto& e : its_mandatory_elements) { + policy_manager_impl::get()->load(e, true); + } + + for (auto f : its_failed) + VSOMEIP_WARNING << __func__ << ": Reading of configuration file \"" + << f << "\" failed. Configuration may be incomplete."; + + result = (its_failed.empty() && !its_mandatory_elements.empty()); + if (result) + policy_manager_impl::get()->set_is_policy_extension_loaded(_client_host, true); + } + + return result; +} +#endif // !VSOMEIP_DISABLE_SECURITY + bool configuration_impl::check_routing_credentials( - client_t _client, uint32_t _uid, uint32_t _gid) const { - return (_client != get_id(routing_host_)) || - security::get()->check_routing_credentials(_client, _uid, _gid); + client_t _client, const vsomeip_sec_client_t *_sec_client) const { + + return (_client != get_id(routing_.host_.name_) || + VSOMEIP_SEC_OK == security::authenticate_router(_sec_client)); } bool configuration_impl::remote_offer_info_add(service_t _service, @@ -418,46 +487,56 @@ bool configuration_impl::remote_offer_info_remove(service_t _service, void configuration_impl::read_data(const std::set &_input, std::vector &_elements, std::set &_failed, - bool _mandatory_only) { + bool _mandatory_only, bool _read_second_level) { for (auto i : _input) { if (utility::is_file(i)) { - if (is_mandatory(i) == _mandatory_only) { - boost::property_tree::ptree its_tree; - try { - boost::property_tree::json_parser::read_json(i, its_tree); - _elements.push_back({ i, its_tree }); - } - catch (boost::property_tree::json_parser_error &e) { - #ifdef _WIN32 - e; // silence MSVC warning C4101 - #endif - _failed.insert(i); - } - } + load_policy_data(i, _elements, _failed, _mandatory_only); } else if (utility::is_folder(i)) { + // Use the map to ensure the configuration files are read in + // the ascending order of their names. This allows to use + // specific configuration file names to overwrite generic + // (or generated) parts of the configuration. + std::map its_names; boost::filesystem::path its_path(i); for (auto j = boost::filesystem::directory_iterator(its_path); j != boost::filesystem::directory_iterator(); j++) { - auto its_file_path = j->path(); - if (!boost::filesystem::is_directory(its_file_path)) { - const std::string& its_name = its_file_path.string(); - if (is_mandatory(its_name) == _mandatory_only) { - boost::property_tree::ptree its_tree; - try { - boost::property_tree::json_parser::read_json(its_name, its_tree); - _elements.push_back({its_name, its_tree}); - } - catch (...) { - _failed.insert(its_name); - } - } + if (!boost::filesystem::is_directory(j->path())) { + its_names[j->path().string()] = _mandatory_only; + } else if(_read_second_level) { + //_read_second_level to read the second level folders only after + // the start, without this the ECU block + std::string name = j->path().string() + "/vsomeip_security.json"; + if (utility::is_file(name)) + its_names[name] = true; } } + + for (const auto &n : its_names) + load_policy_data(n.first, _elements, _failed, n.second); } } } +void configuration_impl::load_policy_data(const std::string &_input, + std::vector &_elements, std::set &_failed, + bool _mandatory_only) { + if (is_mandatory(_input) == _mandatory_only) { +#ifndef VSOMEIP_DISABLE_SECURITY + if (policy_manager_impl::get()->is_policy_extension(_input)) { + policy_manager_impl::get()->set_policy_extension_base_path(_input); + } +#endif + boost::property_tree::ptree its_tree; + try { + boost::property_tree::json_parser::read_json(_input, its_tree); + _elements.push_back({ _input, its_tree }); + } + catch (boost::property_tree::json_parser_error&) { + _failed.insert(_input); + } + } +} bool configuration_impl::load_data(const std::vector &_elements, bool _load_mandatory, bool _load_optional) { @@ -513,6 +592,7 @@ bool configuration_impl::load_data(const std::vector &_el load_acceptances(e); load_secure_services(e); load_partitions(e); + load_routing_client_ports(e); } } @@ -531,7 +611,11 @@ bool configuration_impl::load_logging( " Ignoring definition from " + _element.name_); } else { std::string its_value(i->second.data()); - has_console_log_ = (its_value == "true"); + #ifndef ANDROID + has_console_log_ = (its_value == "true"); + #else + has_console_log_ = true; + #endif is_configured_[ET_LOGGING_CONSOLE] = true; } } else if (its_key == "file") { @@ -642,7 +726,55 @@ configuration_impl::load_routing(const configuration_element &_element) { VSOMEIP_WARNING << "Multiple definitions of routing." << " Ignoring definition from " << _element.name_; } else { - routing_host_ = its_routing.data(); + routing_.is_enabled_ = + its_routing.get_optional("enabled").get_value_or(routing_.is_enabled_); + + bool is_loaded = load_routing_host(its_routing, _element.name_) + && load_routing_guests(its_routing); + + if (!is_loaded) { + routing_.host_.name_ = its_routing.data(); + } else { + if (routing_.guests_.unicast_.is_unspecified()) + routing_.guests_.unicast_ = routing_.host_.unicast_; + if (routing_.guests_.ports_.empty()) + routing_.guests_.ports_.insert(std::make_pair(31492, 31999)); + } + + // Try to validate the port configuration. Check whether a range + // contains an even number of ports and whether its starting port + // number fits to the configured routing host port. Correct both + // cases by reducing the range, if necessary. + std::set > its_invalid_ranges; + std::set > its_corrected_ranges; + for (auto &r : routing_.guests_.ports_) { + auto its_pair = std::make_pair(r.first, r.second); + + bool is_even(((r.second - r.first + 1) % 2) == 0); + + // If the routing host port is [un]even, the start number of the + // range shall also be [un]even. + bool is_matching((r.first % 2) == (routing_.host_.port_ % 2)); + if (!is_matching) { + its_pair.first++; + if (is_even) + its_pair.second--; + } else if (!is_even) { + its_pair.second--; + } + + if (!is_even || !is_matching) { + its_invalid_ranges.insert(r); + its_corrected_ranges.insert(its_pair); + } + } + + for (const auto &r : its_invalid_ranges) + routing_.guests_.ports_.erase(r); + + for (const auto &r : its_corrected_ranges) + routing_.guests_.ports_.insert(r); + is_configured_[ET_ROUTING] = true; } } catch (...) { @@ -651,6 +783,140 @@ configuration_impl::load_routing(const configuration_element &_element) { return true; } +bool +configuration_impl::load_routing_host(const boost::property_tree::ptree &_tree, + const std::string &_name) { + + try { + bool has_uid(false), has_gid(false); + uid_t its_uid; + gid_t its_gid; + auto its_host = _tree.get_child("host"); + for (auto i = its_host.begin(); i != its_host.end(); ++i) { + std::string its_key(i->first); + std::string its_value(i->second.data()); + if (its_key == "name") { + routing_.host_.name_ = its_value; + } else if (its_key == "uid" || its_key == "gid") { + std::stringstream its_converter; + if (its_value.find("0x") == 0) { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + if (its_key == "uid") { + its_converter >> its_uid; + has_uid = true; + } else { + its_converter >> its_gid; + has_gid = true; + } + } else if (its_key == "unicast") { +#if VSOMEIP_BOOST_VERSION < 106600 + routing_.host_.unicast_ + = boost::asio::ip::address::from_string(its_value); +#else + routing_.host_.unicast_ + = boost::asio::ip::make_address(its_value); +#endif + } else if (its_key == "port") { + std::stringstream its_converter; + if (its_value.find("0x") == 0) { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + its_converter >> routing_.host_.port_; + } + } + + if (has_uid && has_gid) { + policy_manager_impl::get()->set_routing_credentials(its_uid, its_gid, _name); + } + + } catch (...) { + return (false); + } + return (true); +} + +bool +configuration_impl::load_routing_guests(const boost::property_tree::ptree &_tree) { + + try { + auto its_guests = _tree.get_child("guests"); + for (auto i = its_guests.begin(); i != its_guests.end(); ++i) { + std::string its_key(i->first); + if (its_key == "unicast") { + std::string its_value(i->second.data()); +#if VSOMEIP_BOOST_VERSION < 106600 + routing_.guests_.unicast_ + = boost::asio::ip::address::from_string(its_value); +#else + routing_.guests_.unicast_ + = boost::asio::ip::make_address(its_value); +#endif + } else if (its_key == "ports") { + load_routing_guest_ports(i->second); + } + } + } catch (...) { + // intentionally left empty + } + return (true); +} + +void +configuration_impl::load_routing_guest_ports( + const boost::property_tree::ptree &_tree) { + + try { + for (auto its_range = _tree.begin(); + its_range != _tree.end(); ++its_range) { + + port_t its_first_port(0), its_last_port(0); + for (auto its_element = its_range->second.begin(); + its_element != its_range->second.end(); ++its_element) { + + std::string its_key(its_element->first); + std::string its_value(its_element->second.data()); + + std::stringstream its_converter; + if (its_value.find("0x") == 0) { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + + if (its_key == "first") { + its_converter >> its_first_port; + } else if (its_key == "last") { + its_converter >> its_last_port; + } + } + + if (its_first_port != 0 && its_last_port != 0) { + routing_.guests_.ports_.insert(std::make_pair( + std::min(its_first_port, its_last_port), + std::max(its_first_port, its_last_port))); + } + } + } catch (...) { + } +} + + +void +configuration_impl::load_routing_client_ports(const configuration_element &_element) { + + try { + auto its_ports = _element.tree_.get_child("routing-client-ports"); + load_routing_guest_ports(its_ports); + } + catch (...) { + } +} + bool configuration_impl::load_applications(const configuration_element &_element) { try { @@ -676,10 +942,8 @@ void configuration_impl::load_application_data( std::size_t its_request_debounce_time(VSOMEIP_REQUEST_DEBOUNCE_TIME); std::map> plugins; int its_io_thread_nice_level(VSOMEIP_IO_THREAD_NICE_LEVEL); - std::string its_overlay; -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG + debounce_configuration_t its_debounces; bool has_session_handling(true); -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG for (auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key(i->first); std::string its_value(i->second.data()); @@ -721,14 +985,18 @@ void configuration_impl::load_application_data( } } else if (its_key == "plugins") { plugins = load_plugins(i->second, its_name); - } else if (its_key == "overlay") { - its_overlay = its_value; + } else if (its_key == "debounce") { + try { + for (auto j = i->second.begin(); j != i->second.end(); ++j) { + load_service_debounce(j->second, its_debounces); + } + } catch (...) { + // intentionally empty + } } -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG else if (its_key == "has_session_handling") { has_session_handling = (its_value != "false"); } -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG } if (its_name != "") { if (applications_.find(its_name) == applications_.end()) { @@ -743,15 +1011,18 @@ void configuration_impl::load_application_data( its_id = VSOMEIP_CLIENT_UNSET; } } - applications_[its_name] - = std::make_tuple(its_id, its_max_dispatchers, - its_max_dispatch_time, its_io_thread_count, - its_request_debounce_time, plugins, its_io_thread_nice_level, - its_overlay -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG - , has_session_handling -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG - ); + + applications_[its_name] = { + its_id, + its_max_dispatchers, + its_max_dispatch_time, + its_io_thread_count, + its_request_debounce_time, + plugins, + its_io_thread_nice_level, + its_debounces + , has_session_handling + }; } else { VSOMEIP_WARNING << "Multiple configurations for application " << its_name << ". Ignoring a configuration from " @@ -762,7 +1033,7 @@ void configuration_impl::load_application_data( std::map> configuration_impl::load_plugins( const boost::property_tree::ptree &_tree, - const std::string& _application_name) { + const std::string &_application_name) { std::map> its_plugins; std::string its_name(""); std::string its_type; @@ -788,6 +1059,19 @@ std::map> configuration_impl::load_plugins( its_type = its_inner_value; its_configured[ET_PLUGIN_TYPE] = true; } + } else if (its_inner_key == "additional") { + if (its_configured[ET_PLUGIN_NAME]) { + const boost::property_tree::ptree &its_additional_tree(l->second); + for (auto m = its_additional_tree.begin(); m!= its_additional_tree.end(); ++m) { + for (auto n = m->second.begin(); n != m->second.end(); ++n) { + std::string its_additional_inner_key(n->first); + std::string its_additional_inner_value(n->second.data()); + plugins_additional_[_application_name][its_name] + [its_additional_inner_key] = + its_additional_inner_value; + } + } + } } else { //support old config format (type : name) plugin_config_data_t its_plugin_data = { @@ -820,13 +1104,13 @@ void configuration_impl::add_plugin(std::mapsecond.data(); - its_filter->is_positive_ = (its_value == "positive"); + if (its_value == "negative") + its_filter->ftype_ = vsomeip_v3::trace::filter_type_e::NEGATIVE; + else if (its_value == "header-only") + its_filter->ftype_ = vsomeip_v3::trace::filter_type_e::HEADER_ONLY; + else + its_filter->ftype_ = vsomeip_v3::trace::filter_type_e::POSITIVE; } else { load_trace_filter_expressions(i->second, its_key, its_filter); } @@ -941,7 +1230,7 @@ void configuration_impl::load_trace_filter( its_filter->channels_.push_back("TC"); // default } - if (!its_filter->is_range_ || its_filter->matches_.size() == 2) { + if (!its_filter->is_range_ || its_filter->matches_.size() > 0) { trace_->filters_.push_back(its_filter); } } @@ -1052,7 +1341,7 @@ void configuration_impl::load_trace_filter_match( void configuration_impl::load_unicast_address(const configuration_element &_element) { try { std::string its_value = _element.tree_.get("unicast"); - if (!is_overlay_ && is_configured_[ET_UNICAST]) { + if (is_configured_[ET_UNICAST]) { VSOMEIP_WARNING << "Multiple definitions for unicast." "Ignoring definition from " << _element.name_; } else { @@ -1066,13 +1355,35 @@ void configuration_impl::load_unicast_address(const configuration_element &_elem void configuration_impl::load_netmask(const configuration_element &_element) { try { - std::string its_value = _element.tree_.get("netmask"); - if (!is_overlay_ && is_configured_[ET_NETMASK]) { - VSOMEIP_WARNING << "Multiple definitions for netmask." - "Ignoring definition from " << _element.name_; - } else { - netmask_ = netmask_.from_string(its_value); - is_configured_[ET_NETMASK] = true; + auto its_value = _element.tree_.get_optional("netmask"); + if (its_value) { + if (is_configured_[ET_NETMASK]) { + VSOMEIP_WARNING << "Multiple definitions for netmask/prefix." + "Ignoring netmask definition from " << _element.name_; + } else { + netmask_ = netmask_.from_string(*its_value); + is_configured_[ET_NETMASK] = true; + } + } + + its_value = _element.tree_.get_optional("prefix"); + if (its_value) { + if (is_configured_[ET_NETMASK]) { + VSOMEIP_WARNING << "Multiple definitions for prefix/netmask." + "Ignoring prefix definition from " << _element.name_; + } else { + std::stringstream its_converter; + its_converter << *its_value; + its_converter >> std::dec >> prefix_; + + // Convert to netmask as this is used for IPv4. + uint32_t its_netmask = (std::numeric_limits::max() + << (std::numeric_limits::digits - prefix_)) + & std::numeric_limits::max(); + netmask_ = boost::asio::ip::address_v4(its_netmask); + + is_configured_[ET_NETMASK] = true; + } } } catch (...) { // intentionally left empty! @@ -1082,7 +1393,7 @@ void configuration_impl::load_netmask(const configuration_element &_element) { void configuration_impl::load_device(const configuration_element &_element) { try { std::string its_value = _element.tree_.get("device"); - if (!is_overlay_ && is_configured_[ET_DEVICE]) { + if (is_configured_[ET_DEVICE]) { VSOMEIP_WARNING << "Multiple definitions for device." "Ignoring definition from " << _element.name_; } else { @@ -1097,7 +1408,7 @@ void configuration_impl::load_device(const configuration_element &_element) { void configuration_impl::load_network(const configuration_element &_element) { try { std::string its_value(_element.tree_.get("network")); - if (!is_overlay_ && is_configured_[ET_NETWORK]) { + if (is_configured_[ET_NETWORK]) { VSOMEIP_WARNING << "Multiple definitions for network." "Ignoring definition from " << _element.name_; } else { @@ -1112,7 +1423,7 @@ void configuration_impl::load_network(const configuration_element &_element) { void configuration_impl::load_diagnosis_address(const configuration_element &_element) { try { std::string its_value = _element.tree_.get("diagnosis"); - if (!is_overlay_ && is_configured_[ET_DIAGNOSIS]) { + if (is_configured_[ET_DIAGNOSIS]) { VSOMEIP_WARNING << "Multiple definitions for diagnosis." "Ignoring definition from " << _element.name_; } else { @@ -1127,7 +1438,7 @@ void configuration_impl::load_diagnosis_address(const configuration_element &_el is_configured_[ET_DIAGNOSIS] = true; } std::string its_mask = _element.tree_.get("diagnosis_mask"); - if (!is_overlay_ && is_configured_[ET_DIAGNOSIS_MASK]) { + if (is_configured_[ET_DIAGNOSIS_MASK]) { VSOMEIP_WARNING << "Multiple definitions for diagnosis_mask." "Ignoring definition from " << _element.name_; } else { @@ -1189,7 +1500,7 @@ void configuration_impl::load_service_discovery( std::string its_value(i->second.data()); std::stringstream its_converter; if (its_key == "enable") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_ENABLE]) { + if (is_configured_[ET_SERVICE_DISCOVERY_ENABLE]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.enabled." " Ignoring definition from " << _element.name_; } else { @@ -1197,7 +1508,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_ENABLE] = true; } } else if (its_key == "multicast") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_MULTICAST]) { + if (is_configured_[ET_SERVICE_DISCOVERY_MULTICAST]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.multicast." " Ignoring definition from " << _element.name_; } else { @@ -1205,7 +1516,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_MULTICAST] = true; } } else if (its_key == "port") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_PORT]) { + if (is_configured_[ET_SERVICE_DISCOVERY_PORT]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.port." " Ignoring definition from " << _element.name_; } else { @@ -1218,7 +1529,7 @@ void configuration_impl::load_service_discovery( } } } else if (its_key == "protocol") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_PROTOCOL]) { + if (is_configured_[ET_SERVICE_DISCOVERY_PROTOCOL]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.protocol." " Ignoring definition from " << _element.name_; } else { @@ -1226,7 +1537,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_PROTOCOL] = true; } } else if (its_key == "initial_delay_min") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN]) { + if (is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.initial_delay_min." " Ignoring definition from " << _element.name_; } else { @@ -1235,7 +1546,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MIN] = true; } } else if (its_key == "initial_delay_max") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MAX]) { + if (is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MAX]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.initial_delay_max." " Ignoring definition from " << _element.name_; } else { @@ -1244,7 +1555,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_INITIAL_DELAY_MAX] = true; } } else if (its_key == "repetitions_base_delay") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY]) { + if (is_configured_[ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.repetition_base_delay." " Ignoring definition from " << _element.name_; } else { @@ -1253,7 +1564,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_REPETITION_BASE_DELAY] = true; } } else if (its_key == "repetitions_max") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_REPETITION_MAX]) { + if (is_configured_[ET_SERVICE_DISCOVERY_REPETITION_MAX]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.repetition_max." " Ignoring definition from " << _element.name_; } else { @@ -1266,7 +1577,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_REPETITION_MAX] = true; } } else if (its_key == "ttl") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_TTL]) { + if (is_configured_[ET_SERVICE_DISCOVERY_TTL]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.ttl." " Ignoring definition from " << _element.name_; } else { @@ -1281,7 +1592,7 @@ void configuration_impl::load_service_discovery( else is_configured_[ET_SERVICE_DISCOVERY_TTL] = true; } } else if (its_key == "cyclic_offer_delay") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_CYCLIC_OFFER_DELAY]) { + if (is_configured_[ET_SERVICE_DISCOVERY_CYCLIC_OFFER_DELAY]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.cyclic_offer_delay." " Ignoring definition from " << _element.name_; } else { @@ -1290,7 +1601,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_CYCLIC_OFFER_DELAY] = true; } } else if (its_key == "request_response_delay") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_REQUEST_RESPONSE_DELAY]) { + if (is_configured_[ET_SERVICE_DISCOVERY_REQUEST_RESPONSE_DELAY]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.request_response_delay." " Ignoring definition from " << _element.name_; } else { @@ -1299,7 +1610,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_REQUEST_RESPONSE_DELAY] = true; } } else if (its_key == "offer_debounce_time") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_OFFER_DEBOUNCE_TIME]) { + if (is_configured_[ET_SERVICE_DISCOVERY_OFFER_DEBOUNCE_TIME]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.offer_debounce." " Ignoring definition from " << _element.name_; } else { @@ -1308,7 +1619,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_OFFER_DEBOUNCE_TIME] = true; } } else if (its_key == "ttl_factor_offers") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_OFFERS]) { + if (is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_OFFERS]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.ttl_factor_offers." " Ignoring definition from " << _element.name_; } else { @@ -1316,7 +1627,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_OFFERS] = true; } } else if (its_key == "ttl_factor_subscriptions") { - if (!is_overlay_ && is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_SUBSCRIPTIONS]) { + if (is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_SUBSCRIPTIONS]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.ttl_factor_subscriptions." " Ignoring definition from " << _element.name_; } else { @@ -1324,7 +1635,7 @@ void configuration_impl::load_service_discovery( is_configured_[ET_SERVICE_DISCOVERY_TTL_FACTOR_SUBSCRIPTIONS] = true; } } else if (its_key == "max_remote_subscribers") { - if (!is_overlay_ && is_configured_[ET_MAX_REMOTE_SUBSCRIBERS]) { + if (is_configured_[ET_MAX_REMOTE_SUBSCRIBERS]) { VSOMEIP_WARNING << "Multiple definitions for service_discovery.max_remote_subscribers." " Ignoring definition from " << _element.name_; } else { @@ -1393,7 +1704,7 @@ void configuration_impl::load_npdu_default_timings(const configuration_element & const std::string rresp("max-retention-time-response"); try { if (_element.tree_.get_child_optional(ndt)) { - if (!is_overlay_ && is_configured_[ET_NPDU_DEFAULT_TIMINGS]) { + if (is_configured_[ET_NPDU_DEFAULT_TIMINGS]) { VSOMEIP_WARNING << "Multiple definitions of " << ndt << " Ignoring definition from " << _element.name_; } else { @@ -1403,7 +1714,7 @@ void configuration_impl::load_npdu_default_timings(const configuration_element & its_time = std::chrono::nanoseconds( std::strtoull(e.second.data().c_str(), NULL, 10) * 1000000); - } catch (const std::exception& e) { + } catch (const std::exception&) { continue; } if (e.first.data() == dreq) { @@ -1481,9 +1792,6 @@ void configuration_impl::load_service( its_service->multicast_address_ = ""; its_service->multicast_port_ = ILLEGAL_PORT; its_service->protocol_ = "someip"; - its_service->major_ = DEFAULT_MAJOR; - its_service->minor_ = DEFAULT_MINOR; - its_service->ttl_ = DEFAULT_TTL; for (auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key(i->first); @@ -1548,14 +1856,6 @@ void configuration_impl::load_service( its_converter >> its_service->service_; } else if (its_key == "instance") { its_converter >> its_service->instance_; - } else if (its_key == "major") { - unsigned int temp; - its_converter >> temp; - its_service->major_ = static_cast(temp); - } else if (its_key == "minor") { - its_converter >> its_service->minor_; - } else if (its_key == "ttl") { - its_converter >> its_service->ttl_; } } } @@ -1625,6 +1925,10 @@ void configuration_impl::load_event( event_t its_event_id(0); bool its_is_field(false); reliability_type_e its_reliability(reliability_type_e::RT_UNKNOWN); + uint32_t its_cycle_value; + std::chrono::milliseconds its_cycle(std::chrono::milliseconds::zero()); + bool its_change_resets_cycle(false); + bool its_update_on_change(true); for (auto j = i->second.begin(); j != i->second.end(); ++j) { std::string its_key(j->first); @@ -1644,28 +1948,26 @@ void configuration_impl::load_event( its_reliability = reliability_type_e::RT_RELIABLE; else its_reliability = reliability_type_e::RT_UNRELIABLE; + } else if (its_key == "cycle") { + std::stringstream its_converter; + its_converter << std::dec << its_value; + its_converter >> its_cycle_value; + its_cycle = std::chrono::milliseconds(its_cycle_value); + } else if (its_key == "change_resets_cycle") { + its_change_resets_cycle = (its_value == "true"); + } else if (its_key == "update_on_change") { + its_update_on_change = (its_value == "true"); } } if (its_event_id > 0) { - std::shared_ptr its_event; - auto found_event = _service->events_.find(its_event_id); if (found_event != _service->events_.end()) { - if (found_event->second->is_placeholder_) { - its_event = found_event->second; - } else { - VSOMEIP_ERROR << "Multiple configurations for event [" - << std::hex << _service->service_ << "." - << _service->instance_ << "." - << its_event_id << "]"; - } + VSOMEIP_INFO << "Multiple configurations for event [" + << std::hex << _service->service_ << "." + << _service->instance_ << "." + << its_event_id << "]."; } else { - its_event = std::make_shared(its_event_id); - _service->events_[its_event_id] = its_event; - } - - if (its_event) { // If event reliability type was not configured, if (its_reliability == reliability_type_e::RT_UNKNOWN) { if (_service->unreliable_ != ILLEGAL_PORT) { @@ -1681,9 +1983,11 @@ void configuration_impl::load_event( ? "RT_RELIABLE" : "RT_UNRELIABLE"); } - its_event->is_placeholder_ = false; - its_event->reliability_ = its_reliability; - its_event->is_field_ = its_is_field; + std::shared_ptr its_event = std::make_shared( + its_event_id, its_is_field, its_reliability, + its_cycle, its_change_resets_cycle, + its_update_on_change); + _service->events_[its_event_id] = its_event; } } } @@ -1747,7 +2051,10 @@ void configuration_impl::load_eventgroup( if (find_event != _service->events_.end()) { its_event = find_event->second; } else { - its_event = std::make_shared(its_event_id); + its_event = std::make_shared(its_event_id, + false, reliability_type_e::RT_UNRELIABLE, + std::chrono::milliseconds::zero(), + false, true); } if (its_event) { its_event->groups_.push_back(its_eventgroup); @@ -2138,9 +2445,46 @@ void configuration_impl::load_permissions(const configuration_element &_element) } void configuration_impl::load_security(const configuration_element &_element) { - security::get()->load(_element); + + try { + auto its_security = _element.tree_.get_child_optional("security"); + if (its_security) { + is_security_enabled_ = true; + + auto its_audit_mode = its_security->get_child_optional("check_credentials"); + if (its_audit_mode) { + if (is_configured_[ET_SECURITY_AUDIT_MODE]) { + VSOMEIP_WARNING << "Multiple definitions for security audit mode (" + << "(check_credentials). Ignoring definition from " + << _element.name_; + } else { + is_security_audit_ = (its_audit_mode->data() != "true"); + is_configured_[ET_SECURITY_AUDIT_MODE] = true; + } + } + + auto its_remote_access = its_security->get_child_optional("allow_remote_clients"); + if (its_remote_access) { + if (is_configured_[ET_SECURITY_REMOTE_ACCESS]) { + VSOMEIP_WARNING << "Multiple definitions for security audit mode (" + << "(check_credentials). Ignoring definition from " + << _element.name_; + } else { + is_remote_access_allowed_ = (its_remote_access->data() == "true"); + is_configured_[ET_SECURITY_REMOTE_ACCESS] = true; + } + } + } + + } catch (...) { + } + +#ifndef VSOMEIP_DISABLE_SECURITY + policy_manager_impl::get()->load(_element); +#endif // !VSOMEIP_DISABLE_SECURITY } + void configuration_impl::load_selective_broadcasts_support(const configuration_element &_element) { try { auto its_service_discovery = _element.tree_.get_child("supports_selective_broadcasts"); @@ -2220,14 +2564,14 @@ configuration_impl::load_partition(const boost::property_tree::ptree &_tree) { << std::dec << static_cast(its_partition_id) << " ["; - for (const auto &i : its_partition_members) { - for (const auto j : i.second) { - partitions_[i.first][j] = its_partition_id; + for (const auto &p : its_partition_members) { + for (const auto &m : p.second) { + partitions_[p.first][m] = its_partition_id; its_log << "<" << std::setw(4) << std::setfill('0') << std::hex - << i.first << "." + << p.first << "." << std::setw(4) << std::setfill('0') << std::hex - << j + << m << ">"; } } @@ -2294,6 +2638,10 @@ const boost::asio::ip::address& configuration_impl::get_netmask() const { return netmask_; } +unsigned short configuration_impl::get_prefix() const { + return prefix_; +} + const std::string &configuration_impl::get_device() const { return device_; } @@ -2371,15 +2719,16 @@ uint16_t configuration_impl::get_unreliable_port(service_t _service, } void configuration_impl::get_configured_timing_requests( - service_t _service, std::string _ip_target, + service_t _service, const std::string &_ip_target, std::uint16_t _port_target, method_t _method, std::chrono::nanoseconds *_debounce_time, std::chrono::nanoseconds *_max_retention_time) const { + if (_debounce_time == nullptr || _max_retention_time == nullptr) { return; } - service *its_service = find_service_by_ip_port(_service, _ip_target, - _port_target); + + auto its_service = find_service(_service, _ip_target, _port_target); if (its_service) { auto find_method = its_service->debounce_times_requests_.find(_method); if (find_method != its_service->debounce_times_requests_.end()) { @@ -2388,20 +2737,21 @@ void configuration_impl::get_configured_timing_requests( return; } } + *_debounce_time = npdu_default_debounce_requ_; *_max_retention_time = npdu_default_max_retention_requ_; } void configuration_impl::get_configured_timing_responses( - service_t _service, std::string _ip_service, + service_t _service, const std::string &_ip_service, std::uint16_t _port_service, method_t _method, std::chrono::nanoseconds *_debounce_time, std::chrono::nanoseconds *_max_retention_time) const { if (_debounce_time == nullptr || _max_retention_time == nullptr) { return; } - service *its_service = find_service_by_ip_port(_service, _ip_service, - _port_service); + + auto its_service = find_service(_service, _ip_service, _port_service); if (its_service) { auto find_method = its_service->debounce_times_responses_.find(_method); if (find_method != its_service->debounce_times_responses_.end()) { @@ -2410,43 +2760,11 @@ void configuration_impl::get_configured_timing_responses( return; } } + *_debounce_time = npdu_default_debounce_resp_; *_max_retention_time = npdu_default_max_retention_resp_; } -major_version_t configuration_impl::get_major_version(service_t _service, - instance_t _instance) const { - std::lock_guard its_lock(services_mutex_); - major_version_t its_major = DEFAULT_MAJOR; - auto its_service = find_service_unlocked(_service, _instance); - if (its_service) - its_major = its_service->major_; - - return its_major; -} - -minor_version_t configuration_impl::get_minor_version(service_t _service, - instance_t _instance) const { - std::lock_guard its_lock(services_mutex_); - minor_version_t its_minor = DEFAULT_MINOR; - auto its_service = find_service_unlocked(_service, _instance); - if (its_service) - its_minor = its_service->minor_; - - return its_minor; -} - -ttl_t configuration_impl::get_ttl(service_t _service, - instance_t _instance) const { - std::lock_guard its_lock(services_mutex_); - ttl_t its_ttl = DEFAULT_TTL; - auto its_service = find_service_unlocked(_service, _instance); - if (its_service) - its_ttl = its_service->ttl_; - - return its_ttl; -} - bool configuration_impl::is_someip(service_t _service, instance_t _instance) const { auto its_service = find_service(_service, _instance); @@ -2499,7 +2817,7 @@ bool configuration_impl::get_client_port( return false; } -bool configuration_impl::has_enabled_magic_cookies(std::string _address, +bool configuration_impl::has_enabled_magic_cookies(const std::string &_address, uint16_t _port) const { bool has_enabled(false); auto find_address = magic_cookies_.find(_address); @@ -2512,9 +2830,51 @@ bool configuration_impl::has_enabled_magic_cookies(std::string _address, return has_enabled; } +bool configuration_impl::is_routing_enabled() const { + return (routing_.is_enabled_); +} + +const std::string & +configuration_impl::get_routing_host_name() const { + + return (routing_.host_.name_); +} + +const boost::asio::ip::address & +configuration_impl::get_routing_host_address() const { + + return (routing_.host_.unicast_); +} + +port_t +configuration_impl::get_routing_host_port() const { + + return (routing_.host_.port_); +} + +const boost::asio::ip::address & +configuration_impl::get_routing_guest_address() const { + + return (routing_.guests_.unicast_); +} + +std::set > +configuration_impl::get_routing_guest_ports() const { -const std::string & configuration_impl::get_routing_host() const { - return routing_host_; + return (routing_.guests_.ports_); +} + +bool +configuration_impl::is_local_routing() const { + + bool is_local(true); + try { + is_local = routing_.host_.unicast_.is_unspecified() || + routing_.host_.unicast_.is_multicast(); + } catch (...) { + } + + return (is_local); } client_t configuration_impl::get_id(const std::string &_name) const { @@ -2522,7 +2882,7 @@ client_t configuration_impl::get_id(const std::string &_name) const { auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - its_client = std::get<0>(found_application->second); + its_client = found_application->second.client_; } return its_client; @@ -2533,13 +2893,13 @@ bool configuration_impl::is_configured_client_id(client_t _id) const { } std::size_t configuration_impl::get_request_debouncing(const std::string &_name) const { - size_t debounce_time = VSOMEIP_REQUEST_DEBOUNCE_TIME; + size_t its_request_debouncing(VSOMEIP_REQUEST_DEBOUNCE_TIME); auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - debounce_time = std::get<4>(found_application->second); + its_request_debouncing = found_application->second.request_debouncing_; } - return debounce_time; + return its_request_debouncing; } std::size_t configuration_impl::get_io_thread_count(const std::string &_name) const { @@ -2547,7 +2907,7 @@ std::size_t configuration_impl::get_io_thread_count(const std::string &_name) co auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - its_io_thread_count = std::get<3>(found_application->second); + its_io_thread_count = found_application->second.thread_count_; } return its_io_thread_count; @@ -2558,7 +2918,7 @@ int configuration_impl::get_io_thread_nice_level(const std::string &_name) const auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - its_io_thread_nice_level = std::get<6>(found_application->second); + its_io_thread_nice_level = found_application->second.nice_level_; } return its_io_thread_nice_level; @@ -2566,11 +2926,12 @@ int configuration_impl::get_io_thread_nice_level(const std::string &_name) const std::size_t configuration_impl::get_max_dispatchers( const std::string &_name) const { - std::size_t its_max_dispatchers = VSOMEIP_MAX_DISPATCHERS; + + std::size_t its_max_dispatchers(VSOMEIP_MAX_DISPATCHERS); auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - its_max_dispatchers = std::get<1>(found_application->second); + its_max_dispatchers = found_application->second.max_dispatchers_; } return its_max_dispatchers; @@ -2582,23 +2943,22 @@ std::size_t configuration_impl::get_max_dispatch_time( auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - its_max_dispatch_time = std::get<2>(found_application->second); + its_max_dispatch_time = found_application->second.max_dispatch_time_; } return its_max_dispatch_time; } -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG + bool configuration_impl::has_session_handling(const std::string &_name) const { bool its_value(true); auto found_application = applications_.find(_name); if (found_application != applications_.end()) - its_value = std::get<8>(found_application->second); + its_value = found_application->second.has_session_handling_; return (its_value); } -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG std::set > configuration_impl::get_remote_services() const { @@ -2657,7 +3017,7 @@ void configuration_impl::trim(std::string &_s) { std::find_if( _s.begin(), _s.end(), - std::not1(std::ptr_fun(isspace)) + [](unsigned char ch) { return !std::isspace(ch); } ) ); @@ -2665,7 +3025,7 @@ void configuration_impl::trim(std::string &_s) { std::find_if( _s.rbegin(), _s.rend(), - std::not1(std::ptr_fun(isspace))).base(), + [](unsigned char ch) { return !std::isspace(ch); }).base(), _s.end() ); } @@ -2715,6 +3075,32 @@ std::shared_ptr configuration_impl::find_client(service_t _service, return nullptr; } +void configuration_impl::get_event_update_properties( + service_t _service, instance_t _instance, event_t _event, + std::chrono::milliseconds &_cycle, + bool &_change_resets_cycle, bool &_update_on_change) const { + + auto find_service = services_.find(_service); + if (find_service != services_.end()) { + auto find_instance = find_service->second.find(_instance); + if (find_instance != find_service->second.end()) { + auto its_service = find_instance->second; + auto find_event = its_service->events_.find(_event); + if (find_event != its_service->events_.end()) { + _cycle = find_event->second->cycle_; + _change_resets_cycle = find_event->second->change_resets_cycle_; + _update_on_change = find_event->second->update_on_change_; + return; + } + } + } + + _cycle = std::chrono::milliseconds::zero(); + _change_resets_cycle = false; + _update_on_change = true; +} + + bool configuration_impl::find_port(uint16_t &_port, uint16_t _remote, bool _reliable, std::map > &_used_client_ports) const { bool is_configured(false); @@ -2726,10 +3112,12 @@ bool configuration_impl::find_port(uint16_t &_port, uint16_t _remote, bool _reli is_configured = true; uint16_t its_port(ILLEGAL_PORT); if ((*it)->last_used_client_port_[_reliable] != ILLEGAL_PORT && - is_in_port_range(((*it)->last_used_client_port_[_reliable])++, + is_in_port_range(((*it)->last_used_client_port_[_reliable]), (*it)->client_ports_[_reliable])) { - its_port = ((*it)->last_used_client_port_[_reliable])++; + its_port = ++((*it)->last_used_client_port_[_reliable]); + ((*it)->last_used_client_port_[_reliable])++; } else { + ((*it)->last_used_client_port_[_reliable])++; // on initial start of port search if ((*it)->last_used_client_port_[_reliable] == ILLEGAL_PORT) { its_port = (*it)->client_ports_[_reliable].first; @@ -2892,19 +3280,23 @@ std::shared_ptr configuration_impl::find_service_unlocked(service_t _se return its_service; } -service* configuration_impl::find_service_by_ip_port( - service_t _service, const std::string& _ip, std::uint16_t _port) const { - service *its_service(0); - auto find_ip = services_by_ip_port_.find(_ip); - if(find_ip != services_by_ip_port_.end()) { - auto find_port = find_ip->second.find(_port); - if(find_port != find_ip->second.end()) { +std::shared_ptr +configuration_impl::find_service(service_t _service, + const std::string &_address, std::uint16_t _port) const { + + std::shared_ptr its_service; + + auto find_address = services_by_ip_port_.find(_address); + if (find_address != services_by_ip_port_.end()) { + auto find_port = find_address->second.find(_port); + if(find_port != find_address->second.end()) { auto find_service = find_port->second.find(_service); if(find_service != find_port->second.end()) { - its_service = find_service->second.get(); + its_service = find_service->second; } } } + return its_service; } @@ -2944,7 +3336,7 @@ std::uint32_t configuration_impl::get_max_message_size_local() const { // add sizes of the the routing_manager_proxy's messages // to the routing_manager stub - return std::uint32_t(its_max_message_size + VSOMEIP_SEND_COMMAND_SIZE); + return std::uint32_t(its_max_message_size + protocol::SEND_COMMAND_HEADER_SIZE); } std::uint32_t configuration_impl::get_max_message_size_reliable( @@ -2970,7 +3362,7 @@ std::uint32_t configuration_impl::get_buffer_shrink_threshold() const { return buffer_shrink_threshold_; } -bool configuration_impl::supports_selective_broadcasts(boost::asio::ip::address _address) const { +bool configuration_impl::supports_selective_broadcasts(const boost::asio::ip::address &_address) const { return supported_selective_addresses.find(_address.to_string()) != supported_selective_addresses.end(); } @@ -3076,20 +3468,28 @@ std::uint32_t configuration_impl::get_permissions_shm() const { std::map> configuration_impl::get_plugins( const std::string &_name) const { - std::map> result; + + std::map> its_plugins; auto found_application = applications_.find(_name); if (found_application != applications_.end()) { - result = std::get<5>(found_application->second); + its_plugins = found_application->second.plugins_; } - return result; + return its_plugins; } void configuration_impl::set_configuration_path(const std::string &_path) { configuration_path_ = _path; } +std::map configuration_impl::get_additional_data( + const std::string &_application_name, + const std::string &_plugin_name) { + + return plugins_additional_[_application_name][_plugin_name]; +} + bool configuration_impl::is_e2e_enabled() const { return e2e_enabled_; } @@ -3361,17 +3761,20 @@ configuration_impl::load_debounce(const configuration_element &_element) { try { auto its_debounce = _element.tree_.get_child("debounce"); for (auto i = its_debounce.begin(); i != its_debounce.end(); ++i) { - load_service_debounce(i->second); + load_service_debounce(i->second, debounces_); } } catch (...) { } } void -configuration_impl::load_service_debounce(const boost::property_tree::ptree &_tree) { +configuration_impl::load_service_debounce( + const boost::property_tree::ptree &_tree, + debounce_configuration_t &_debounces) { + service_t its_service(0); instance_t its_instance(0); - std::map> its_debounces; + std::map> its_debounces; for (auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key(i->first); @@ -3410,23 +3813,27 @@ configuration_impl::load_service_debounce(const boost::property_tree::ptree &_tr return; } } - debounces_[its_service][its_instance] = its_debounces; + _debounces[its_service][its_instance] = its_debounces; } } -void configuration_impl::load_events_debounce( +void +configuration_impl::load_events_debounce( const boost::property_tree::ptree &_tree, - std::map> &_debounces) { + std::map > &_debounces) { + for (auto i = _tree.begin(); i != _tree.end(); ++i) { load_event_debounce(i->second, _debounces); } } -void configuration_impl::load_event_debounce( +void +configuration_impl::load_event_debounce( const boost::property_tree::ptree &_tree, - std::map> &_debounces) { + std::map > &_debounces) { + event_t its_event(0); - std::shared_ptr its_debounce = std::make_shared(); + auto its_debounce = std::make_shared(); for (auto i = _tree.begin(); i != _tree.end(); ++i) { std::string its_key(i->first); @@ -3518,20 +3925,21 @@ configuration_impl::load_acceptances( const configuration_element &_element) { std::string its_acceptances_key("acceptances"); + try { + auto its_acceptances = _element.tree_.get_child_optional(its_acceptances_key); + if (its_acceptances) { + if (is_configured_[ET_SD_ACCEPTANCE_REQUIRED]) { + VSOMEIP_WARNING << "Multiple definitions of " << its_acceptances_key + << " Ignoring definition from " << _element.name_; + return; + } - if (is_configured_[ET_SD_ACCEPTANCE_REQUIRED]) { - VSOMEIP_WARNING << "Multiple definitions of " << its_acceptances_key - << " Ignoring definition from " << _element.name_; - return; - } + for (auto i = its_acceptances->begin(); i != its_acceptances->end(); ++i) { + load_acceptance_data(i->second); + } - try { - auto its_acceptances = _element.tree_.get_child(its_acceptances_key); - for (auto i = its_acceptances.begin(); i != its_acceptances.end(); ++i) { - load_acceptance_data(i->second); + is_configured_[ET_SD_ACCEPTANCE_REQUIRED] = true; } - - is_configured_[ET_SD_ACCEPTANCE_REQUIRED] = true; } catch (...) { // Intentionally left empty } @@ -3560,7 +3968,6 @@ configuration_impl::load_acceptance_data( std::string its_value(i->second.data()); if (its_key == "address") { - boost::system::error_code ec; its_address = boost::asio::ip::address::from_string(its_value); } else if (its_key == "path") { its_path = its_value; @@ -3643,37 +4050,8 @@ configuration_impl::load_acceptance_data( } } - // If no ports are specified, use default! - if (its_ports.empty()) { - const auto its_optional_client = boost::icl::interval::closed(30491, 30499); - const auto its_optional_client_spare = boost::icl::interval::closed(30898, 30998); - const auto its_optional_server = boost::icl::interval::closed(30501, 30599); - - // optional - its_ports.operator [](false).first.insert(its_optional_client); - its_ports.operator [](false).first.insert(its_optional_client_spare); - its_ports.operator [](false).first.insert(its_optional_server); - its_ports.operator [](true).first.insert(its_optional_client); - its_ports.operator [](true).first.insert(its_optional_client_spare); - its_ports.operator [](true).first.insert(its_optional_server); - - // secure - const auto its_secure_client = boost::icl::interval::closed(32491, 32499); - const auto its_secure_client_spare = boost::icl::interval::closed(32898, 32998); - const auto its_secure_server = boost::icl::interval::closed(32501, 32599); - - its_ports.operator [](false).second.insert(its_secure_client); - its_ports.operator [](false).second.insert(its_secure_client_spare); - its_ports.operator [](false).second.insert(its_secure_server); - its_ports.operator [](true).second.insert(its_secure_client); - its_ports.operator [](true).second.insert(its_secure_client_spare); - its_ports.operator [](true).second.insert(its_secure_server); - } - if (!its_address.is_unspecified()) { - sd_acceptance_rules_.insert( - std::make_pair(its_address, - std::make_pair(its_path, its_ports))); + sd_acceptance_rules_[its_address] = std::make_pair(its_path, its_ports); } } catch (...) { // intentionally left empty @@ -3779,20 +4157,88 @@ void configuration_impl::load_someip_tp_for_service( try { std::stringstream its_converter; for (const auto& method : _tree) { - method_t its_method = 0xFFFF; + method_t its_method(0); + uint16_t its_max_segment_length(VSOMEIP_TP_MAX_SEGMENT_LENGTH_DEFAULT); + uint32_t its_separation_time(0); + const std::string its_value(method.second.data()); - if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { - its_converter << std::hex << its_value; + if (its_value.empty()) { + for (const auto &its_data : method.second) { + const std::string its_value(its_data.second.data()); + if (!its_value.empty()) { + if (its_data.first == "method") { + if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + its_converter >> its_method; + } else if (its_data.first == "max-segment-length") { + its_converter << std::dec << its_value; + its_converter >> its_max_segment_length; + + // Segment length must be multiple of 16 + // Ensure this by subtracting the rest + std::uint16_t its_rest = std::uint16_t(its_max_segment_length % 16); + if (its_rest != 0) { + VSOMEIP_WARNING << "SOMEIP/TP: max-segment-length must be multiple of 16. Corrected " + << std::dec << its_max_segment_length << " to " + << std::dec << its_max_segment_length-its_rest; + + its_max_segment_length = std::uint16_t(its_max_segment_length - its_rest); + } + } else if (its_data.first == "separation-time") { + its_converter << std::dec << its_value; + its_converter >> its_separation_time; + its_separation_time *= std::uint32_t(1000); + } + } + its_converter.str(""); + its_converter.clear(); + } } else { - its_converter << std::dec << its_value; + if (its_value.size() > 1 && its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + its_converter >> its_method; + its_converter.str(""); + its_converter.clear(); } - its_converter >> its_method; - its_converter.str(""); - its_converter.clear(); - if (_is_request) { - _service->tp_segment_messages_client_to_service_.insert(its_method); + + if (its_method != 0) { + if (_is_request) { + const auto its_entry = _service->tp_client_config_.find(its_method); + if (its_entry == _service->tp_client_config_.end()) { + _service->tp_client_config_[its_method] + = std::make_pair(its_max_segment_length, its_separation_time); + } else { + VSOMEIP_WARNING << "SOME/IP-TP: Multiple client configurations for method [" + << std::hex << std::setw(4) << std::setfill('0') << _service->service_ << "." + << std::hex << std::setw(4) << std::setfill('0') << _service->instance_ << "." + << std::hex << std::setw(4) << std::setfill('0') << its_method << "]:" + << " using (" + << std::dec << its_entry->second.first << ", " + << std::dec << its_entry->second.second << ")"; + } + } else { + const auto its_entry = _service->tp_service_config_.find(its_method); + if (its_entry == _service->tp_service_config_.end()) { + _service->tp_service_config_[its_method] + = std::make_pair(its_max_segment_length, its_separation_time); + } else { + VSOMEIP_WARNING << "SOME/IP-TP: Multiple service configurations for method [" + << std::hex << std::setw(4) << std::setfill('0') << _service->service_ << "." + << std::hex << std::setw(4) << std::setfill('0') << _service->instance_ << "." + << std::hex << std::setw(4) << std::setfill('0') << its_method << "]:" + << " using (" + << std::dec << its_entry->second.first << ", " + << std::dec << its_entry->second.second << ")"; + } + } } else { - _service->tp_segment_messages_service_to_client_.insert(its_method); + VSOMEIP_ERROR << "SOME/IP-TP configuration contains invalid entry. No valid method specified!"; } } } catch (...) { @@ -3802,18 +4248,18 @@ void configuration_impl::load_someip_tp_for_service( void configuration_impl::load_udp_receive_buffer_size(const configuration_element &_element) { - const std::string urbs("udp-receive-buffer-size"); + const std::string its_buffer_size("udp-receive-buffer-size"); try { - if (_element.tree_.get_child_optional(urbs)) { + if (_element.tree_.get_child_optional(its_buffer_size)) { if (is_configured_[ET_UDP_RECEIVE_BUFFER_SIZE]) { - VSOMEIP_WARNING << "Multiple definitions of " << urbs + VSOMEIP_WARNING << "Multiple definitions of " << its_buffer_size << " Ignoring definition from " << _element.name_; } else { - const std::string s(_element.tree_.get_child(urbs).data()); + const std::string its_data(_element.tree_.get_child(its_buffer_size).data()); try { - udp_receive_buffer_size_ = std::stoi(s.c_str(), NULL, 10); + udp_receive_buffer_size_ = std::stoi(its_data.c_str(), nullptr, 10); } catch (const std::exception &e) { - VSOMEIP_ERROR<< __func__ << ": " << urbs << " " << e.what(); + VSOMEIP_ERROR<< __func__ << ": " << its_buffer_size << " " << e.what(); } is_configured_[ET_UDP_RECEIVE_BUFFER_SIZE] = true; } @@ -3872,19 +4318,38 @@ void configuration_impl::load_secure_service(const boost::property_tree::ptree & } } -std::shared_ptr configuration_impl::get_debounce( +std::shared_ptr +configuration_impl::get_debounce(const std::string &_name, service_t _service, instance_t _instance, event_t _event) const { + + // Try to find application (client) specific debounce configuration + auto found_application = applications_.find(_name); + if (found_application != applications_.end()) { + auto found_service = found_application->second.debounces_.find(_service); + if (found_service != found_application->second.debounces_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + auto found_event = found_instance->second.find(_event); + if (found_event != found_instance->second.end()) { + return (found_event->second); + } + } + } + } + + // If no application specific configuration was found, search for a + // generic auto found_service = debounces_.find(_service); if (found_service != debounces_.end()) { auto found_instance = found_service->second.find(_instance); if (found_instance != found_service->second.end()) { auto found_event = found_instance->second.find(_event); if (found_event != found_instance->second.end()) { - return found_event->second; + return (found_event->second); } } } - return nullptr; + return (nullptr); } void @@ -4141,13 +4606,6 @@ void configuration_impl::set_sd_acceptance_rule( } } -void configuration_impl::set_sd_acceptance_rules( - const sd_acceptance_rules_t& _rules, bool _enable) { - // Unused, only still available to preserve compatibility - (void)_rules; - (void)_enable; -} - configuration::sd_acceptance_rules_t configuration_impl::get_sd_acceptance_rules() { std::lock_guard its_lock(sd_acceptance_required_ips_mutex_); return sd_acceptance_rules_; @@ -4155,6 +4613,7 @@ configuration::sd_acceptance_rules_t configuration_impl::get_sd_acceptance_rules void configuration_impl::set_sd_acceptance_rules_active( const boost::asio::ip::address& _address, bool _enable) { + std::lock_guard its_lock(sd_acceptance_required_ips_mutex_); if (_enable) { sd_acceptance_rules_active_.insert(_address); } else { @@ -4171,64 +4630,84 @@ bool configuration_impl::is_secure_service(service_t _service, instance_t _insta } int configuration_impl::get_udp_receive_buffer_size() const { - return udp_receive_buffer_size_; + + return (udp_receive_buffer_size_); } -bool configuration_impl::tp_segment_messages_client_to_service( - service_t _service, std::string _ip_target, std::uint16_t _port_target, +bool configuration_impl::is_tp_client( + service_t _service, + const std::string &_address, std::uint16_t _port, method_t _method) const { + bool ret(false); - const service* const its_service = find_service_by_ip_port(_service, - _ip_target, _port_target); + + const auto its_service + = find_service(_service, _address, _port); + if (its_service) { - ret = (its_service->tp_segment_messages_client_to_service_.find(_method) - != its_service->tp_segment_messages_client_to_service_.end()); + ret = (its_service->tp_client_config_.find(_method) + != its_service->tp_client_config_.end()); } + return ret; } -bool configuration_impl::tp_segment_messages_service_to_client( - service_t _service, std::string _ip_service, - std::uint16_t _port_service, method_t _method) const { +bool configuration_impl::is_tp_service( + service_t _service, + const std::string &_address, std::uint16_t _port, + method_t _method) const { + bool ret(false); - const service* const its_service = find_service_by_ip_port(_service, - _ip_service, _port_service); + const auto its_service + = find_service(_service, _address, _port); if (its_service) { - ret = (its_service->tp_segment_messages_service_to_client_.find(_method) - != its_service->tp_segment_messages_service_to_client_.end()); + ret = (its_service->tp_service_config_.find(_method) + != its_service->tp_service_config_.end()); } + return ret; } -#ifdef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS -bool -configuration_impl::has_overlay(const std::string &_name) const { - auto its_application = applications_.find(_name); - return (its_application != applications_.end() - && !std::get<7>(its_application->second).empty()); -} +void configuration_impl::get_tp_configuration( + service_t _service, instance_t _instance, method_t _method, + bool _is_client, + std::uint16_t &_max_segment_length, std::uint32_t &_separation_time) const { -void -configuration_impl::load_overlay(const std::string &_name) { - std::set its_input; - std::vector its_elements; - std::set its_failed; + const auto its_info = find_service(_service, _instance); + if (its_info) { + if (_is_client) { + auto its_method = its_info->tp_client_config_.find(_method); - auto its_application = applications_.find(_name); - if (its_application != applications_.end()) { - std::string its_overlay(std::get<7>(its_application->second)); + // Note: The following two lines do not make sense now, + // but they will when TP configuration is reworked + if (its_method == its_info->tp_client_config_.end()) + its_method = its_info->tp_client_config_.find(ANY_METHOD); - its_input.insert(its_overlay); - read_data(its_input, its_elements, its_failed, false); + if (its_method != its_info->tp_client_config_.end()) { + _max_segment_length = its_method->second.first; + _separation_time = its_method->second.second; + return; + } + } else { + auto its_method = its_info->tp_service_config_.find(_method); - for (const auto& f : its_failed) - VSOMEIP_ERROR << "Reading configuration data from " << f << " failed!"; + // Note: The following two lines do not make sense now, + // but they will when TP configuration is reworked + if (its_method == its_info->tp_service_config_.end()) + its_method = its_info->tp_service_config_.find(ANY_METHOD); - is_overlay_ = true; - load_data(its_elements, true, true); + if (its_method != its_info->tp_service_config_.end()) { + _max_segment_length = its_method->second.first; + _separation_time = its_method->second.second; + return; + } + } } + + // No configuration defined --> set default values + _max_segment_length = VSOMEIP_TP_MAX_SEGMENT_LENGTH_DEFAULT; + _separation_time = 0; } -#endif // VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS std::uint32_t configuration_impl::get_shutdown_timeout() const { return shutdown_timeout_; @@ -4272,5 +4751,45 @@ configuration_impl::get_partition_id( return (its_id); } +reliability_type_e +configuration_impl::get_reliability_type( + const boost::asio::ip::address &_reliable_address, + const uint16_t &_reliable_port, + const boost::asio::ip::address &_unreliable_address, + const uint16_t &_unreliable_port) const { + + if (_reliable_port != ILLEGAL_PORT + && _unreliable_port != ILLEGAL_PORT + && !_reliable_address.is_unspecified() + && !_unreliable_address.is_unspecified()) { + return reliability_type_e::RT_BOTH; + } else if (_unreliable_port != ILLEGAL_PORT + && !_unreliable_address.is_unspecified()) { + return reliability_type_e::RT_UNRELIABLE; + } else if (_reliable_port != ILLEGAL_PORT + && !_reliable_address.is_unspecified()) { + return reliability_type_e::RT_RELIABLE; + } + return reliability_type_e::RT_UNKNOWN; +} + +bool +configuration_impl::is_security_enabled() const { + + return (is_security_enabled_); +} + +bool +configuration_impl::is_security_audit() const { + + return (is_security_audit_); +} + +bool +configuration_impl::is_remote_access_allowed() const { + + return (is_remote_access_allowed_); +} + } // namespace cfg } // namespace vsomeip_v3 diff --git a/implementation/configuration/src/configuration_plugin_impl.cpp b/implementation/configuration/src/configuration_plugin_impl.cpp index df175f3..2293c09 100644 --- a/implementation/configuration/src/configuration_plugin_impl.cpp +++ b/implementation/configuration/src/configuration_plugin_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -22,31 +22,29 @@ configuration_plugin_impl::~configuration_plugin_impl() { } std::shared_ptr -configuration_plugin_impl::get_configuration(const std::string &_name) { +configuration_plugin_impl::get_configuration(const std::string &_name, + const std::string &_path) { + std::lock_guard its_lock(mutex_); if (!default_) { - default_ = std::make_shared(); + default_ = std::make_shared(_path); default_->load(_name); } + return default_; -#ifdef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS - auto its_configuration(default_); - if (its_configuration->has_overlay(_name)) { - VSOMEIP_INFO << "Loading configuration overlay for \"" << _name << "\""; - auto its_iterator = configurations_.find(_name); - if (its_iterator != configurations_.end()) { - its_configuration = its_iterator->second; - } else { - its_configuration = std::make_shared( - *(its_configuration.get())); - its_configuration->load_overlay(_name); - configurations_[_name] = its_configuration; - } +#if 0 + std::shared_ptr its_configuration; + auto its_iterator = configurations_.find(_name); + if (its_iterator != configurations_.end()) { + its_configuration = its_iterator->second; + } else { + its_configuration = std::make_shared(_path); + its_configuration->load(_name); + configurations_[_name] = its_configuration; } - return its_configuration; -#else - return default_; -#endif // VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS + + return (its_configuration); +#endif } } // namespace vsomeip_v3 diff --git a/implementation/e2e_protection/include/buffer/buffer.hpp b/implementation/e2e_protection/include/buffer/buffer.hpp index 8583ede..95205f8 100644 --- a/implementation/e2e_protection/include/buffer/buffer.hpp +++ b/implementation/e2e_protection/include/buffer/buffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/crc/crc.hpp b/implementation/e2e_protection/include/crc/crc.hpp index b8d5688..de0ccec 100644 --- a/implementation/e2e_protection/include/crc/crc.hpp +++ b/implementation/e2e_protection/include/crc/crc.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/e2e_provider.hpp b/implementation/e2e_protection/include/e2e/profile/e2e_provider.hpp index 41d7487..51e42e1 100644 --- a/implementation/e2e_protection/include/e2e/profile/e2e_provider.hpp +++ b/implementation/e2e_protection/include/e2e/profile/e2e_provider.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -37,4 +37,3 @@ public: } // namespace vsomeip_v3 #endif // VSOMEIP_V3_E2E_PROVIDER_HPP - diff --git a/implementation/e2e_protection/include/e2e/profile/e2e_provider_impl.hpp b/implementation/e2e_protection/include/e2e/profile/e2e_provider_impl.hpp index 62db2e2..631f87f 100644 --- a/implementation/e2e_protection/include/e2e/profile/e2e_provider_impl.hpp +++ b/implementation/e2e_protection/include/e2e/profile/e2e_provider_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -71,4 +71,3 @@ private: } // namespace vsomeip_v3 #endif // VSOMEIP_V3_E2E_PROVIDER_IMPL_HPP - diff --git a/implementation/e2e_protection/include/e2e/profile/profile01/checker.hpp b/implementation/e2e_protection/include/e2e/profile/profile01/checker.hpp index 4184996..8f97113 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile01/checker.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile01/checker.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile01/profile_01.hpp b/implementation/e2e_protection/include/e2e/profile/profile01/profile_01.hpp index 54b2d5c..097d9f5 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile01/profile_01.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile01/profile_01.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile01/protector.hpp b/implementation/e2e_protection/include/e2e/profile/profile01/protector.hpp index 13bd524..7e37993 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile01/protector.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile01/protector.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile04/checker.hpp b/implementation/e2e_protection/include/e2e/profile/profile04/checker.hpp index c16eb10..2ed3ebd 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile04/checker.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile04/checker.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,6 +6,8 @@ #ifndef VSOMEIP_V3_E2E_PROFILE04_CHECKER_HPP #define VSOMEIP_V3_E2E_PROFILE04_CHECKER_HPP +#include + #include "../profile04/profile_04.hpp" #include "../profile_interface/checker.hpp" @@ -20,14 +22,14 @@ public: // [SWS_E2E_00389] initialize state explicit profile_04_checker(const profile_config &_config) : - config_(_config), counter_(0xffff) {} + config_(_config) {} void check(const e2e_buffer &_buffer, instance_t _instance, e2e::profile_interface::check_status_t &_generic_check_status) override final; private: bool verify_input(const e2e_buffer &_buffer) const; - bool verify_counter(uint16_t _received_counter) const; + bool verify_counter(instance_t _instance, uint16_t _received_counter); bool read_16(const e2e_buffer &_buffer, uint16_t &_data, size_t _index) const; bool read_32(const e2e_buffer &_buffer, uint32_t &_data, size_t _index) const; @@ -35,7 +37,7 @@ private: std::mutex check_mutex_; profile_config config_; - uint16_t counter_; + std::map counter_; }; } // namespace profile_04 diff --git a/implementation/e2e_protection/include/e2e/profile/profile04/profile_04.hpp b/implementation/e2e_protection/include/e2e/profile/profile04/profile_04.hpp index 88be05c..11a7ee7 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile04/profile_04.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile04/profile_04.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile04/protector.hpp b/implementation/e2e_protection/include/e2e/profile/profile04/protector.hpp index fd4a6e7..eab0a9a 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile04/protector.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile04/protector.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,7 +6,9 @@ #ifndef VSOMEIP_V3_E2E_PROFILE04_PROTECTOR_HPP #define VSOMEIP_V3_E2E_PROFILE04_PROTECTOR_HPP +#include #include + #include "../profile04/profile_04.hpp" #include "../profile_interface/protector.hpp" @@ -19,20 +21,21 @@ public: protector(void) = delete; explicit protector(const profile_config &_config) - : config_(_config), counter_(0) {}; + : config_(_config) {} void protect(e2e_buffer &_buffer, instance_t _instance) override final; private: bool verify_inputs(e2e_buffer &_buffer); - void increment_counter(); + uint16_t get_counter(instance_t _instance) const; + void increment_counter(instance_t _instance); void write_16(e2e_buffer &_buffer, uint16_t _data, size_t _index); void write_32(e2e_buffer &_buffer, uint32_t _data, size_t _index); private: profile_config config_; - uint16_t counter_; + std::map counter_; std::mutex protect_mutex_; }; diff --git a/implementation/e2e_protection/include/e2e/profile/profile_custom/checker.hpp b/implementation/e2e_protection/include/e2e/profile/profile_custom/checker.hpp index e233205..94d5456 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile_custom/checker.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile_custom/checker.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp b/implementation/e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp index 244989d..0a97ff1 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile_custom/protector.hpp b/implementation/e2e_protection/include/e2e/profile/profile_custom/protector.hpp index a2ec5d1..2396b5a 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile_custom/protector.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile_custom/protector.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile_interface/checker.hpp b/implementation/e2e_protection/include/e2e/profile/profile_interface/checker.hpp index 12cb6b7..1bdf447 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile_interface/checker.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile_interface/checker.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2e/profile/profile_interface/profile_interface.hpp b/implementation/e2e_protection/include/e2e/profile/profile_interface/profile_interface.hpp index 5fa018c..5079e7e 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile_interface/profile_interface.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile_interface/profile_interface.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,7 +12,7 @@ namespace vsomeip_v3 { namespace e2e { namespace profile_interface { -typedef uint8_t check_status_t; +using check_status_t = std::uint8_t; enum generic_check_status : check_status_t { E2E_OK, E2E_WRONG_CRC, E2E_ERROR}; diff --git a/implementation/e2e_protection/include/e2e/profile/profile_interface/protector.hpp b/implementation/e2e_protection/include/e2e/profile/profile_interface/protector.hpp index 4b02971..20c63d5 100644 --- a/implementation/e2e_protection/include/e2e/profile/profile_interface/protector.hpp +++ b/implementation/e2e_protection/include/e2e/profile/profile_interface/protector.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/include/e2exf/config.hpp b/implementation/e2e_protection/include/e2exf/config.hpp index a022d8c..9c10504 100644 --- a/implementation/e2e_protection/include/e2exf/config.hpp +++ b/implementation/e2e_protection/include/e2exf/config.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/src/buffer/buffer.cpp b/implementation/e2e_protection/src/buffer/buffer.cpp index d50310b..6d82622 100644 --- a/implementation/e2e_protection/src/buffer/buffer.cpp +++ b/implementation/e2e_protection/src/buffer/buffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/src/crc/crc.cpp b/implementation/e2e_protection/src/crc/crc.cpp index 60ddb6c..18c7ec7 100644 --- a/implementation/e2e_protection/src/crc/crc.cpp +++ b/implementation/e2e_protection/src/crc/crc.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -30,7 +30,11 @@ namespace vsomeip_v3 { uint8_t e2e_crc::calculate_profile_01(buffer_view _buffer_view, const uint8_t _start_value) { uint8_t crc = _start_value ^ 0xFFU; for (uint8_t byte : _buffer_view) { - crc = static_cast(lookup_table_profile_01_[static_cast((byte) ^ crc)] ^ (crc >> 8U)); + /* + * XXX Right-shifting 8 bits on uint8_t results in 0 every time. + * It is, quintessentially, shifting all bits into the void. + */ + crc = static_cast(lookup_table_profile_01_[static_cast((byte) ^ crc)]/* ^ (crc >> 8U)*/); } crc = crc ^ 0xFFU; return crc; @@ -181,4 +185,3 @@ const uint32_t e2e_crc::lookup_table_profile_custom_[256] = { }; } // namespace vsomeip_v3 - diff --git a/implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp b/implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp index 111e126..0d05fca 100644 --- a/implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp +++ b/implementation/e2e_protection/src/e2e/profile/e2e_provider_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/e2e_protection/src/e2e/profile/profile01/checker.cpp b/implementation/e2e_protection/src/e2e/profile/profile01/checker.cpp index a5d75d8..d70dac6 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile01/checker.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile01/checker.cpp @@ -1,16 +1,14 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../../../../../e2e_protection/include/e2e/profile/profile01/checker.hpp" -#include -#include -#include -#include #include #include +#include +#include "../../../../include/e2e/profile/profile01/checker.hpp" + namespace vsomeip_v3 { namespace e2e { namespace profile01 { diff --git a/implementation/e2e_protection/src/e2e/profile/profile01/profile_01.cpp b/implementation/e2e_protection/src/e2e/profile/profile01/profile_01.cpp index 358dd4e..032bac0 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile01/profile_01.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile01/profile_01.cpp @@ -1,14 +1,10 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../../../../../e2e_protection/include/e2e/profile/profile01/profile_01.hpp" -#include "../../../../../e2e_protection/include/crc/crc.hpp" -#include -#include -#include -#include +#include "../../../../include/e2e/profile/profile01/profile_01.hpp" +#include "../../../../include/crc/crc.hpp" namespace vsomeip_v3 { namespace e2e { diff --git a/implementation/e2e_protection/src/e2e/profile/profile01/protector.cpp b/implementation/e2e_protection/src/e2e/profile/profile01/protector.cpp index e5cb4ba..0f514a0 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile01/protector.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile01/protector.cpp @@ -1,16 +1,14 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../../../../../e2e_protection/include/e2e/profile/profile01/protector.hpp" -#include -#include -#include -#include #include +#include +#include "../../../../include/e2e/profile/profile01/protector.hpp" + namespace vsomeip_v3 { namespace e2e { namespace profile01 { diff --git a/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp b/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp index c9761ca..88c0192 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile04/checker.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,10 +6,9 @@ #include #include -#include "../../utility/include/byteorder.hpp" - -#include "../../../../../e2e_protection/include/e2e/profile/profile04/checker.hpp" +#include "../../../../include/e2e/profile/profile04/checker.hpp" +#include "../../../../../utility/include/byteorder.hpp" namespace vsomeip_v3 { namespace e2e { @@ -51,10 +50,9 @@ void profile_04_checker::check(const e2e_buffer &_buffer, instance_t _instance, uint32_t its_data_id(uint32_t(_instance) << 24 | config_.data_id_); if (its_received_data_id == its_data_id && static_cast(its_received_length) == _buffer.size() - && verify_counter(its_received_counter)) { - _generic_check_status = e2e::profile_interface::generic_check_status::E2E_OK; + && verify_counter(_instance, its_received_counter)) { + _generic_check_status = e2e::profile_interface::generic_check_status::E2E_OK; } - counter_ = its_received_counter; } } } @@ -72,18 +70,19 @@ profile_04_checker::verify_input(const e2e_buffer &_buffer) const { } bool -profile_04_checker::verify_counter(uint16_t _received_counter) const { +profile_04_checker::verify_counter(instance_t _instance, uint16_t _received_counter) { - static bool has_counter(false); uint16_t its_delta(0); - if (has_counter) { - if (counter_ < _received_counter) - its_delta = uint16_t(_received_counter - counter_); + auto find_counter = counter_.find(_instance); + if (find_counter != counter_.end()) { + uint16_t its_counter = find_counter->second; + if (its_counter < _received_counter) + its_delta = uint16_t(_received_counter - its_counter); else - its_delta = uint16_t(uint16_t(0xffff) - counter_ + _received_counter); + its_delta = uint16_t(uint16_t(0xffff) - its_counter + _received_counter); } else { - has_counter = true; + counter_[_instance] = _received_counter; } return (its_delta <= config_.max_delta_counter_); diff --git a/implementation/e2e_protection/src/e2e/profile/profile04/profile_04.cpp b/implementation/e2e_protection/src/e2e/profile/profile04/profile_04.cpp index 05ab5e9..43a9380 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile04/profile_04.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile04/profile_04.cpp @@ -1,15 +1,10 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include -#include -#include -#include - -#include "../../../../../e2e_protection/include/e2e/profile/profile04/profile_04.hpp" -#include "../../../../../e2e_protection/include/crc/crc.hpp" +#include "../../../../include/crc/crc.hpp" +#include "../../../../include/e2e/profile/profile04/profile_04.hpp" namespace vsomeip_v3 { namespace e2e { diff --git a/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp b/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp index a9287f2..bc7d0db 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile04/protector.cpp @@ -1,14 +1,13 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include -#include "../../../../../e2e_protection/include/e2e/profile/profile04/protector.hpp" - #include -#include "../../utility/include/byteorder.hpp" +#include "../../../../include/e2e/profile/profile04/protector.hpp" +#include "../../../../../utility/include/byteorder.hpp" namespace vsomeip_v3 { namespace e2e { @@ -31,7 +30,7 @@ protector::protect(e2e_buffer &_buffer, instance_t _instance) { write_16(_buffer, static_cast(_buffer.size()), 0); /** @req [SWS_E2E_00365] */ - write_16(_buffer, counter_, 2); + write_16(_buffer, get_counter(_instance), 2); /** @req [SWS_E2E_00366] */ uint32_t its_data_id(uint32_t(_instance) << 24 | config_.data_id_); @@ -44,7 +43,7 @@ protector::protect(e2e_buffer &_buffer, instance_t _instance) { write_32(_buffer, its_crc, 8); /** @req [SWS_E2E_00369] */ - increment_counter(); + increment_counter(_instance); } } @@ -71,9 +70,26 @@ protector::write_32(e2e_buffer &_buffer, uint32_t _data, size_t _index) { _buffer[config_.offset_ + _index + 3] = VSOMEIP_LONG_BYTE0(_data); } +uint16_t +protector::get_counter(instance_t _instance) const { + + uint16_t its_counter(0); + + auto find_counter = counter_.find(_instance); + if (find_counter != counter_.end()) + its_counter = find_counter->second; + + return (its_counter); +} + void -protector::increment_counter() { - counter_++; +protector::increment_counter(instance_t _instance) { + + auto find_counter = counter_.find(_instance); + if (find_counter != counter_.end()) + find_counter->second++; + else + counter_[_instance] = 1; } } // namespace profile04 diff --git a/implementation/e2e_protection/src/e2e/profile/profile_custom/checker.cpp b/implementation/e2e_protection/src/e2e/profile/profile_custom/checker.cpp index 9916a2f..bce5af9 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile_custom/checker.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile_custom/checker.cpp @@ -1,16 +1,14 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../../../../../e2e_protection/include/e2e/profile/profile_custom/checker.hpp" -#include -#include -#include -#include #include #include +#include +#include "../../../../include/e2e/profile/profile_custom/checker.hpp" + namespace vsomeip_v3 { namespace e2e { namespace profile_custom { diff --git a/implementation/e2e_protection/src/e2e/profile/profile_custom/profile_custom.cpp b/implementation/e2e_protection/src/e2e/profile/profile_custom/profile_custom.cpp index 5ab53ca..4e2936e 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile_custom/profile_custom.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile_custom/profile_custom.cpp @@ -1,14 +1,10 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../../../../../e2e_protection/include/e2e/profile/profile_custom/profile_custom.hpp" -#include "../../../../../e2e_protection/include/crc/crc.hpp" -#include -#include -#include -#include +#include "../../../../include/crc/crc.hpp" +#include "../../../../include/e2e/profile/profile_custom/profile_custom.hpp" namespace vsomeip_v3 { namespace e2e { diff --git a/implementation/e2e_protection/src/e2e/profile/profile_custom/protector.cpp b/implementation/e2e_protection/src/e2e/profile/profile_custom/protector.cpp index c71f91f..1fd0ccb 100644 --- a/implementation/e2e_protection/src/e2e/profile/profile_custom/protector.cpp +++ b/implementation/e2e_protection/src/e2e/profile/profile_custom/protector.cpp @@ -1,16 +1,9 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../../../../../e2e_protection/include/e2e/profile/profile_custom/protector.hpp" - -#include -#include -#include -#include -#include -#include +#include "../../../../include/e2e/profile/profile_custom/protector.hpp" namespace vsomeip_v3 { namespace e2e { diff --git a/implementation/e2e_protection/src/e2exf/config.cpp b/implementation/e2e_protection/src/e2exf/config.cpp index 20a3b71..6f124d3 100644 --- a/implementation/e2e_protection/src/e2exf/config.cpp +++ b/implementation/e2e_protection/src/e2exf/config.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/endpoints/include/buffer.hpp b/implementation/endpoints/include/buffer.hpp index af0582d..089a526 100644 --- a/implementation/endpoints/include/buffer.hpp +++ b/implementation/endpoints/include/buffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,13 +11,18 @@ #include #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +#define io_context io_service +#else +# include +#endif #include #include #include -#ifdef _WIN32 +#if defined(_WIN32) && !defined(_MSVC_LANG) #define DEFAULT_NANOSECONDS_MAX 1000000000 #else #define DEFAULT_NANOSECONDS_MAX std::chrono::nanoseconds::max() @@ -25,37 +30,41 @@ namespace vsomeip_v3 { -typedef std::vector message_buffer_t; -typedef std::shared_ptr message_buffer_ptr_t; +using message_buffer_t = std::vector; +using message_buffer_ptr_t = std::shared_ptr; +#if 0 struct timing { timing() : debouncing_(0), maximum_retention_(DEFAULT_NANOSECONDS_MAX) {}; std::chrono::nanoseconds debouncing_; std::chrono::nanoseconds maximum_retention_; }; +#endif struct train { - train(boost::asio::io_service& _io) : buffer_(std::make_shared()), - departure_(DEFAULT_NANOSECONDS_MAX), - minimal_debounce_time_(DEFAULT_NANOSECONDS_MAX), - minimal_max_retention_time_(DEFAULT_NANOSECONDS_MAX), - last_departure_(std::chrono::steady_clock::now() - std::chrono::hours(1)), - departure_timer_(std::make_shared(_io)) {}; + train() + : buffer_(std::make_shared()), + minimal_debounce_time_(DEFAULT_NANOSECONDS_MAX), + minimal_max_retention_time_(DEFAULT_NANOSECONDS_MAX), + departure_(std::chrono::steady_clock::now() + std::chrono::hours(6)) { + }; + + void reset() { + buffer_ = std::make_shared(); + passengers_.clear(); + minimal_debounce_time_ = DEFAULT_NANOSECONDS_MAX; + minimal_max_retention_time_ = DEFAULT_NANOSECONDS_MAX; + departure_ = std::chrono::steady_clock::now() + std::chrono::hours(6); + } message_buffer_ptr_t buffer_; - std::chrono::nanoseconds departure_; + std::set > passengers_; + std::chrono::nanoseconds minimal_debounce_time_; std::chrono::nanoseconds minimal_max_retention_time_; - std::chrono::steady_clock::time_point last_departure_; - std::shared_ptr departure_timer_; - std::set > passengers_; - void update_departure_time_and_stop_departure() { - departure_ = departure_timer_->expires_from_now(); - boost::system::error_code ec; - departure_timer_->cancel(ec); - } + std::chrono::steady_clock::time_point departure_; }; diff --git a/implementation/endpoints/include/client_endpoint.hpp b/implementation/endpoints/include/client_endpoint.hpp index 3429a92..372a122 100644 --- a/implementation/endpoints/include/client_endpoint.hpp +++ b/implementation/endpoints/include/client_endpoint.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,12 +12,7 @@ namespace vsomeip_v3 { class client_endpoint : public virtual endpoint { public: - virtual ~client_endpoint() -#ifndef ANDROID - {} -#else - ; -#endif + virtual ~client_endpoint() {} virtual bool get_remote_address(boost::asio::ip::address &_address) const = 0; virtual std::uint16_t get_remote_port() const = 0; diff --git a/implementation/endpoints/include/client_endpoint_impl.hpp b/implementation/endpoints/include/client_endpoint_impl.hpp index 518e696..f7e7567 100644 --- a/implementation/endpoints/include/client_endpoint_impl.hpp +++ b/implementation/endpoints/include/client_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,15 +6,15 @@ #ifndef VSOMEIP_V3_CLIENT_ENDPOINT_IMPL_HPP_ #define VSOMEIP_V3_CLIENT_ENDPOINT_IMPL_HPP_ +#include #include #include #include #include -#include #include +#include #include -#include #include #include #include @@ -35,13 +35,13 @@ template class client_endpoint_impl: public endpoint_impl, public client_endpoint, public std::enable_shared_from_this > { public: - typedef typename Protocol::endpoint endpoint_type; - typedef typename Protocol::socket socket_type; + using endpoint_type = typename Protocol::endpoint; + using socket_type = typename Protocol::socket; client_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, - boost::asio::io_service &_io, + boost::asio::io_context &_io, std::uint32_t _max_message_size, configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration); @@ -56,7 +56,7 @@ public: const byte_t *_data, uint32_t _size); bool flush(); - void prepare_stop(endpoint::prepare_stop_handler_t _handler, service_t _service); + void prepare_stop(const endpoint::prepare_stop_handler_t &_handler, service_t _service); virtual void stop(); virtual void restart(bool _force = false) = 0; @@ -78,6 +78,7 @@ public: public: void connect_cbk(boost::system::error_code const &_error); void wait_connect_cbk(boost::system::error_code const &_error); + void wait_connecting_cbk(boost::system::error_code const &_error); virtual void send_cbk(boost::system::error_code const &_error, std::size_t _bytes, const message_buffer_ptr_t& _sent_msg); void flush_cbk(boost::system::error_code const &_error); @@ -94,8 +95,8 @@ protected: CONNECTED, ESTABLISHED }; - message_buffer_ptr_t get_front(); - virtual void send_queued(message_buffer_ptr_t _buffer) = 0; + std::pair get_front(); + virtual void send_queued(std::pair &_entry) = 0; virtual void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, @@ -103,10 +104,13 @@ protected: void shutdown_and_close_socket(bool _recreate_socket); void shutdown_and_close_socket_unlocked(bool _recreate_socket); void start_connect_timer(); + void start_connecting_timer(); typename endpoint_impl::cms_ret_e check_message_size( const std::uint8_t * const _data, std::uint32_t _size); bool check_queue_limit(const uint8_t *_data, std::uint32_t _size) const; - void queue_train(bool _queue_size_zero_on_entry); + void queue_train(const std::shared_ptr &_train, + bool _queue_size_zero_on_entry); + void update_last_departure(); protected: mutable std::mutex socket_mutex_; @@ -121,10 +125,20 @@ protected: std::atomic state_; std::atomic reconnect_counter_; - // send data - train train_; + std::mutex connecting_timer_mutex_; + boost::asio::steady_timer connecting_timer_; + std::atomic connecting_timeout_; + - std::deque queue_; + // send data + std::shared_ptr train_; + std::map > > dispatched_trains_; + boost::asio::steady_timer dispatch_timer_; + std::chrono::steady_clock::time_point last_departure_; + std::atomic has_last_departure_; + + std::deque > queue_; std::size_t queue_size_; mutable std::mutex mutex_; @@ -133,7 +147,7 @@ protected: std::atomic local_port_; - boost::asio::io_service::strand strand_; + boost::asio::io_context::strand strand_; private: virtual void set_local_port() = 0; @@ -142,8 +156,13 @@ private: method_t _method) const = 0; virtual std::uint32_t get_max_allowed_reconnects() const = 0; virtual void max_allowed_reconnects_reached() = 0; - void send_segments(const tp::tp_split_messages_t &_segments); - void wait_until_debounce_time_reached() const; + void send_segments(const tp::tp_split_messages_t &_segments, + std::uint32_t _separation_time); + + void schedule_train(); + + void start_dispatch_timer(const std::chrono::steady_clock::time_point &_now); + void cancel_dispatch_timer(); }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/credentials.hpp b/implementation/endpoints/include/credentials.hpp index 2fe9060..bb4ee44 100644 --- a/implementation/endpoints/include/credentials.hpp +++ b/implementation/endpoints/include/credentials.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,6 +6,10 @@ #ifndef VSOMEIP_V3_ENDPOINTS_INCLUDE_CREDENTIALS_HPP_ #define VSOMEIP_V3_ENDPOINTS_INCLUDE_CREDENTIALS_HPP_ +#include + +#include + #include namespace vsomeip_v3 { @@ -16,9 +20,10 @@ public: static void deactivate_credentials(const int _fd); - static client_t receive_credentials(const int _fd, uid_t& _uid, gid_t& _gid); + using received_t = std::tuple; + static boost::optional receive_credentials(const int _fd); - static void send_credentials(const int _fd, client_t _client); + static void send_credentials(const int _fd, client_t _client, std::string _client_host); }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/endpoint.hpp b/implementation/endpoints/include/endpoint.hpp index 3eafc3a..f3a76b7 100644 --- a/implementation/endpoints/include/endpoint.hpp +++ b/implementation/endpoints/include/endpoint.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,18 +19,13 @@ class endpoint_definition; class endpoint { public: - typedef std::function error_handler_t; - typedef std::function&, service_t)> prepare_stop_handler_t; + using error_handler_t = std::function; + using prepare_stop_handler_t = std::function&, service_t)>; - virtual ~endpoint() -#ifndef ANDROID - {} -#else - ; -#endif + virtual ~endpoint() {} virtual void start() = 0; - virtual void prepare_stop(prepare_stop_handler_t _handler, + virtual void prepare_stop(const prepare_stop_handler_t &_handler, service_t _service = ANY_SERVICE) = 0; virtual void stop() = 0; @@ -38,8 +33,6 @@ public: virtual bool is_established_or_connected() const = 0; virtual bool send(const byte_t *_data, uint32_t _size) = 0; - virtual bool send(const std::vector& _cmd_header, const byte_t *_data, - uint32_t _size) = 0; virtual bool send_to(const std::shared_ptr _target, const byte_t *_data, uint32_t _size) = 0; virtual bool send_error(const std::shared_ptr _target, @@ -62,7 +55,7 @@ public: virtual void restart(bool _force = false) = 0; - virtual void register_error_handler(error_handler_t _error) = 0; + virtual void register_error_handler(const error_handler_t &_error) = 0; virtual void print_status() = 0; virtual size_t get_queue_size() const = 0; diff --git a/implementation/endpoints/include/endpoint_definition.hpp b/implementation/endpoints/include/endpoint_definition.hpp index 5a7e9eb..2dca226 100644 --- a/implementation/endpoints/include/endpoint_definition.hpp +++ b/implementation/endpoints/include/endpoint_definition.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/endpoints/include/endpoint_host.hpp b/implementation/endpoints/include/endpoint_host.hpp index 2af1697..e5ca6d1 100644 --- a/implementation/endpoints/include/endpoint_host.hpp +++ b/implementation/endpoints/include/endpoint_host.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -23,19 +23,31 @@ namespace vsomeip_v3 { class configuration; class endpoint; +struct multicast_option_t { + std::shared_ptr endpoint_; + bool is_join_; + boost::asio::ip::address address_; +}; + class endpoint_host { public: virtual ~endpoint_host() = default; virtual void on_connect(std::shared_ptr _endpoint) = 0; virtual void on_disconnect(std::shared_ptr _endpoint) = 0; - virtual bool on_bind_error(std::shared_ptr _endpoint, uint16_t _remote_port) = 0; + virtual bool on_bind_error(std::shared_ptr _endpoint, + const boost::asio::ip::address &_remote_address, + uint16_t _remote_port) = 0; virtual void on_error(const byte_t *_data, length_t _length, - endpoint* const _receiver, - const boost::asio::ip::address &_remote_address, - std::uint16_t _remote_port) = 0; + endpoint* const _receiver, + const boost::asio::ip::address &_remote_address, + std::uint16_t _remote_port) = 0; virtual void release_port(uint16_t _port, bool _reliable) = 0; virtual client_t get_client() const = 0; + virtual std::string get_client_host() const = 0; + virtual instance_t find_instance(service_t _service, + endpoint * const _endpoint) const = 0; + virtual void add_multicast_option(const multicast_option_t &_option) = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/endpoint_impl.hpp b/implementation/endpoints/include/endpoint_impl.hpp index 76f4698..730c290 100644 --- a/implementation/endpoints/include/endpoint_impl.hpp +++ b/implementation/endpoints/include/endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,7 +11,6 @@ #include #include -#include #include #include "buffer.hpp" @@ -26,12 +25,12 @@ class routing_host; template class endpoint_impl: public virtual endpoint { public: - typedef typename Protocol::endpoint endpoint_type; + using endpoint_type = typename Protocol::endpoint; endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, - boost::asio::io_service &_io, + boost::asio::io_context &_io, std::uint32_t _max_message_size, configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration); @@ -50,7 +49,7 @@ public: void decrement_use_count(); uint32_t get_use_count(); - void register_error_handler(error_handler_t _error_handler); + void register_error_handler(const error_handler_t &_error_handler); virtual void print_status() = 0; virtual size_t get_queue_size() const = 0; @@ -63,6 +62,7 @@ public: protected: uint32_t find_magic_cookie(byte_t *_buffer, size_t _size); + instance_t get_instance(service_t _service); protected: enum class cms_ret_e : uint8_t { @@ -72,7 +72,7 @@ protected: }; // Reference to service context - boost::asio::io_service &service_; + boost::asio::io_context &io_; // References to hosts std::weak_ptr endpoint_host_; diff --git a/implementation/endpoints/include/endpoint_manager_base.hpp b/implementation/endpoints/include/endpoint_manager_base.hpp index aa21269..fec39cc 100644 --- a/implementation/endpoints/include/endpoint_manager_base.hpp +++ b/implementation/endpoints/include/endpoint_manager_base.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,7 +12,12 @@ #include #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include @@ -23,7 +28,6 @@ namespace vsomeip_v3 { class routing_manager_base; class configuration; -class local_server_endpoint_impl; class routing_host; class endpoint_manager_base @@ -31,7 +35,7 @@ class endpoint_manager_base public endpoint_host { public: endpoint_manager_base(routing_manager_base* const _rm, - boost::asio::io_service& _io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration); virtual ~endpoint_manager_base() = default; @@ -44,23 +48,31 @@ public: std::unordered_set get_connected_clients() const; - std::shared_ptr create_local_server( + std::shared_ptr create_local_server( const std::shared_ptr &_routing_host); // endpoint_host interface virtual void on_connect(std::shared_ptr _endpoint); virtual void on_disconnect(std::shared_ptr _endpoint); - virtual bool on_bind_error(std::shared_ptr _endpoint, uint16_t _remote_port); + virtual bool on_bind_error(std::shared_ptr _endpoint, + const boost::asio::ip::address &_remote_address, + uint16_t _remote_port); virtual void on_error(const byte_t *_data, length_t _length, - endpoint* const _receiver, - const boost::asio::ip::address &_remote_address, - std::uint16_t _remote_port); + endpoint* const _receiver, + const boost::asio::ip::address &_remote_address, + std::uint16_t _remote_port); virtual void release_port(uint16_t _port, bool _reliable); client_t get_client() const; + std::string get_client_host() const; + instance_t find_instance(service_t _service, + endpoint* const _endpoint) const; // Statistics void log_client_states() const; + // Multicast options + void add_multicast_option(const multicast_option_t &_option); + protected: std::map> get_local_endpoints() const; @@ -68,14 +80,23 @@ private: std::shared_ptr create_local_unlocked(client_t _client); std::shared_ptr find_local_unlocked(client_t _client); + bool get_local_server_port(port_t &_port, const std::set &_used_ports) const; + protected: routing_manager_base* const rm_; - boost::asio::io_service& io_; + boost::asio::io_context &io_; std::shared_ptr configuration_; + bool is_local_routing_; + port_t local_port_; // local (client) port when connecting to other + // vsomeip application via TCP + private: mutable std::mutex local_endpoint_mutex_; std::map > local_endpoints_; + + mutable std::mutex create_local_server_endpoint_mutex_; + }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/endpoint_manager_impl.hpp b/implementation/endpoints/include/endpoint_manager_impl.hpp index 3354947..a354fb5 100644 --- a/implementation/endpoints/include/endpoint_manager_impl.hpp +++ b/implementation/endpoints/include/endpoint_manager_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,6 +6,10 @@ #ifndef VSOMEIP_V3_ENDPOINT_MANAGER_IMPL_HPP_ #define VSOMEIP_V3_ENDPOINT_MANAGER_IMPL_HPP_ +#include +#include +#include + #include "../include/endpoint_manager_base.hpp" namespace vsomeip_v3 { @@ -15,9 +19,9 @@ class routing_host; class endpoint_manager_impl : public endpoint_manager_base { public: endpoint_manager_impl(routing_manager_base* const _rm, - boost::asio::io_service& _io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration); - ~endpoint_manager_impl() = default; + ~endpoint_manager_impl(); std::shared_ptr find_or_create_remote_client(service_t _service, instance_t _instance, @@ -66,9 +70,10 @@ public: void print_status() const; - std::shared_ptr create_local_server( - bool* _is_socket_activated, - const std::shared_ptr& _routing_host); + bool create_routing_root( + std::shared_ptr &_root, + bool &_is_socket_activated, + const std::shared_ptr &_host); instance_t find_instance(service_t _service, endpoint* const _endpoint) const; @@ -83,17 +88,30 @@ public: void on_connect(std::shared_ptr _endpoint); void on_disconnect(std::shared_ptr _endpoint); bool on_bind_error(std::shared_ptr _endpoint, + const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port); void on_error(const byte_t *_data, length_t _length, - endpoint* const _receiver, - const boost::asio::ip::address &_remote_address, - std::uint16_t _remote_port); - void release_port(uint16_t _port, bool _reliable); + endpoint* const _receiver, + const boost::asio::ip::address &_remote_address, + std::uint16_t _remote_port); + + void get_used_client_ports( + const boost::asio::ip::address &_remote_address, port_t _remote_port, + std::map > &_used_ports); + void request_used_client_port( + const boost::asio::ip::address &_remote_address, port_t _remote_port, + bool _reliable, port_t _local_port); + void release_used_client_port( + const boost::asio::ip::address &_remote_address, port_t _remote_port, + bool _reliable, port_t _local_port); // Statistics void log_client_states() const; void log_server_states() const; + // add join/leave options + void add_multicast_option(const multicast_option_t &_option); + private: std::shared_ptr find_remote_client(service_t _service, instance_t _instance, @@ -105,40 +123,49 @@ private: const boost::asio::ip::address &_address, uint16_t _local_port, uint16_t _remote_port, bool _reliable); + // process join/leave options + void process_multicast_options(); + private: mutable std::recursive_mutex endpoint_mutex_; // Client endpoints for remote services std::map>>> remote_service_info_; - typedef std::map>>> remote_services_t; + using remote_services_t = + std::map>>>; remote_services_t remote_services_; - typedef std::map - > - > - > - > client_endpoints_by_ip_t; + using client_endpoints_by_ip_t = + std::map>>>>; client_endpoints_by_ip_t client_endpoints_by_ip_; std::map > service_instances_; std::map > service_instances_multicast_; - std::map> used_client_ports_; + std::map > + > + > used_client_ports_; std::mutex used_client_ports_mutex_; // Server endpoints for local services - typedef std::map>> server_endpoints_t; + using server_endpoints_t = std::map>>; server_endpoints_t server_endpoints_; // Multicast endpoint info (notifications) std::map>> multicast_info; + + // Socket option processing (join, leave) + std::mutex options_mutex_; + bool is_processing_options_; + std::condition_variable options_condition_; + std::queue options_queue_; + std::thread options_thread_; }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/local_client_endpoint_impl.hpp b/implementation/endpoints/include/local_client_endpoint_impl.hpp deleted file mode 100644 index 3eae191..0000000 --- a/implementation/endpoints/include/local_client_endpoint_impl.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef VSOMEIP_V3_LOCAL_CLIENT_ENDPOINT_IMPL_HPP_ -#define VSOMEIP_V3_LOCAL_CLIENT_ENDPOINT_IMPL_HPP_ - -#include -#include - -#ifdef _WIN32 -#include -#endif - -#include - -#include "client_endpoint_impl.hpp" - -namespace vsomeip_v3 { - -#ifdef _WIN32 -typedef client_endpoint_impl< - boost::asio::ip::tcp - > local_client_endpoint_base_impl; -#else -typedef client_endpoint_impl< - boost::asio::local::stream_protocol - > local_client_endpoint_base_impl; -#endif - -class local_client_endpoint_impl: public local_client_endpoint_base_impl { -public: - local_client_endpoint_impl(const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, - const endpoint_type& _remote, - boost::asio::io_service &_io, - const std::shared_ptr& _configuration); - - virtual ~local_client_endpoint_impl(); - - void start(); - void stop(); - - bool is_local() const; - - bool get_remote_address(boost::asio::ip::address &_address) const; - std::uint16_t get_remote_port() const; - - void restart(bool _force); - void print_status(); - - bool is_reliable() const; - - // this overrides client_endpoint_impl::send to disable the pull method - // for local communication - bool send(const uint8_t *_data, uint32_t _size); - bool send(const std::vector& _cmd_header, const byte_t *_data, - uint32_t _size); - void get_configured_times_from_endpoint( - service_t _service, method_t _method, - std::chrono::nanoseconds *_debouncing, - std::chrono::nanoseconds *_maximum_retention) const; -private: - void send_queued(message_buffer_ptr_t _buffer); - - void send_magic_cookie(); - - void connect(); - void receive(); - void receive_cbk(boost::system::error_code const &_error, - std::size_t _bytes); - void set_local_port(); - std::string get_remote_information() const; - bool check_packetizer_space(std::uint32_t _size); - bool tp_segmentation_enabled(service_t _service, method_t _method) const; - std::uint32_t get_max_allowed_reconnects() const; - void max_allowed_reconnects_reached(); - - message_buffer_t recv_buffer_; - - // send data - message_buffer_ptr_t send_data_buffer_; -}; - -} // namespace vsomeip_v3 - -#endif // VSOMEIP_V3_LOCAL_CLIENT_ENDPOINT_IMPL_HPP_ diff --git a/implementation/endpoints/include/local_server_endpoint_impl.hpp b/implementation/endpoints/include/local_server_endpoint_impl.hpp deleted file mode 100644 index 8fbb619..0000000 --- a/implementation/endpoints/include/local_server_endpoint_impl.hpp +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_HPP_ -#define VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_HPP_ - -#include -#include -#include -#include - -#include -#include - - -#ifdef _WIN32 -#include -#endif - -#include - -#include "buffer.hpp" -#include "server_endpoint_impl.hpp" - -namespace vsomeip_v3 { - -#ifdef _WIN32 -typedef server_endpoint_impl< - boost::asio::ip::tcp - > local_server_endpoint_base_impl; -#else -typedef server_endpoint_impl< - boost::asio::local::stream_protocol_ext - > local_server_endpoint_base_impl; -#endif - -class local_server_endpoint_impl: public local_server_endpoint_base_impl { - -public: - local_server_endpoint_impl(const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, - const endpoint_type& _local, - boost::asio::io_service &_io, - const std::shared_ptr& _configuration, - bool _is_routing_endpoint); - - local_server_endpoint_impl(const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, - const endpoint_type& _local, - boost::asio::io_service &_io, - int native_socket, - const std::shared_ptr& _configuration, - bool _is_routing_endpoint); - - virtual ~local_server_endpoint_impl(); - - void start(); - void stop(); - - void receive(); - - // this overrides server_endpoint_impl::send to disable the nPDU feature - // for local communication - bool send(const uint8_t *_data, uint32_t _size); - bool send_to(const std::shared_ptr, - const byte_t *_data, uint32_t _size); - bool send_error(const std::shared_ptr _target, - const byte_t *_data, uint32_t _size); - void send_queued(const queue_iterator_type _queue_iterator); - void get_configured_times_from_endpoint( - service_t _service, method_t _method, - std::chrono::nanoseconds *_debouncing, - std::chrono::nanoseconds *_maximum_retention) const; - - bool get_default_target(service_t, endpoint_type &) const; - - bool is_local() const; - - void accept_client_func(); - void print_status(); - - bool is_reliable() const; - std::uint16_t get_local_port() const; - void set_local_port(std::uint16_t _port); - - client_t assign_client(const byte_t *_data, uint32_t _size); - -private: - class connection: public std::enable_shared_from_this { - - public: - typedef std::shared_ptr ptr; - - static ptr create(const std::shared_ptr& _server, - std::uint32_t _max_message_size, - std::uint32_t _buffer_shrink_threshold, - boost::asio::io_service &_io_service); - socket_type & get_socket(); - std::unique_lock get_socket_lock(); - - void start(); - void stop(); - - - void send_queued(const message_buffer_ptr_t& _buffer); - - void set_bound_client(client_t _client); - client_t get_bound_client() const; -#ifndef _WIN32 - void set_bound_uid_gid(uid_t _uid, gid_t _gid); -#endif - - std::size_t get_recv_buffer_capacity() const; - - private: - connection(const std::shared_ptr& _server, - std::uint32_t _max_message_size, - std::uint32_t _initial_recv_buffer_size, - std::uint32_t _buffer_shrink_threshold, - boost::asio::io_service &_io_service); - - void send_cbk(const message_buffer_ptr_t _buffer, - boost::system::error_code const &_error, std::size_t _bytes); - void receive_cbk(boost::system::error_code const &_error, - std::size_t _bytes -#ifndef _WIN32 - , std::uint32_t const &_uid, std::uint32_t const &_gid -#endif - ); - void calculate_shrink_count(); - const std::string get_path_local() const; - const std::string get_path_remote() const; - void handle_recv_buffer_exception(const std::exception &_e); - - std::mutex socket_mutex_; - local_server_endpoint_impl::socket_type socket_; - std::weak_ptr server_; - - const std::uint32_t recv_buffer_size_initial_; - const std::uint32_t max_message_size_; - - message_buffer_t recv_buffer_; - size_t recv_buffer_size_; - std::uint32_t missing_capacity_; - std::uint32_t shrink_count_; - const std::uint32_t buffer_shrink_threshold_; - - client_t bound_client_; -#ifndef _WIN32 - uid_t bound_uid_; - gid_t bound_gid_; -#endif - bool assigned_client_; - }; - - std::mutex acceptor_mutex_; -#ifdef _WIN32 - boost::asio::ip::tcp::acceptor acceptor_; -#else - boost::asio::local::stream_protocol_ext::acceptor acceptor_; -#endif - - typedef std::map connections_t; - std::mutex connections_mutex_; - connections_t connections_; - - const std::uint32_t buffer_shrink_threshold_; - - const bool is_routing_endpoint_; - -private: - bool add_connection(const client_t &_client, - const std::shared_ptr &_connection); - void remove_connection(const client_t &_client); - void accept_cbk(const connection::ptr& _connection, - boost::system::error_code const &_error); - std::string get_remote_information( - const queue_iterator_type _queue_iterator) const; - std::string get_remote_information( - const endpoint_type& _remote) const; - - bool check_packetizer_space(queue_iterator_type _queue_iterator, - message_buffer_ptr_t* _packetizer, - std::uint32_t _size); - bool tp_segmentation_enabled(service_t _service, method_t _method) const; - void send_client_identifier(const client_t &_client); -}; - -} // namespace vsomeip_v3 - -#endif // VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_HPP_ diff --git a/implementation/endpoints/include/local_server_endpoint_impl_receive_op.hpp b/implementation/endpoints/include/local_server_endpoint_impl_receive_op.hpp new file mode 100644 index 0000000..38e1662 --- /dev/null +++ b/implementation/endpoints/include/local_server_endpoint_impl_receive_op.hpp @@ -0,0 +1,118 @@ +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ +#define VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ + +#if VSOMEIP_BOOST_VERSION >= 106600 +#if defined(__linux__) || defined(ANDROID) + +#include + +namespace vsomeip_v3 { + +using socket_type_t = boost::asio::local::stream_protocol::socket; +using receive_handler_t = std::function< + void (boost::system::error_code const &_error, size_t _size, + const std::uint32_t &, const std::uint32_t &)>; + +struct local_server_endpoint_impl_receive_op { + + socket_type_t &socket_; + receive_handler_t handler_; + byte_t *buffer_; + size_t length_; + uid_t uid_; + gid_t gid_; + size_t bytes_; + + void operator()(boost::system::error_code _error) { + + if (!_error) { + if (!socket_.native_non_blocking()) + socket_.native_non_blocking(true, _error); + + for (;;) { + ssize_t its_result; + int its_flags(0); + + // Set buffer + struct iovec its_vec[1]; + its_vec[0].iov_base = buffer_; + its_vec[0].iov_len = length_; + + union { + struct cmsghdr cmh; + char control[CMSG_SPACE(sizeof(struct ucred))]; + } control_un; + + // Set 'control_un' to describe ancillary data that we want to receive + control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); + control_un.cmh.cmsg_level = SOL_SOCKET; + control_un.cmh.cmsg_type = SCM_CREDENTIALS; + + // Build header with all informations to call ::recvmsg + msghdr its_header = msghdr(); + its_header.msg_iov = its_vec; + its_header.msg_iovlen = 1; + its_header.msg_control = control_un.control; + its_header.msg_controllen = sizeof(control_un.control); + + // Call recvmsg and handle its result + errno = 0; + its_result = ::recvmsg(socket_.native_handle(), &its_header, its_flags); + _error = boost::system::error_code(its_result < 0 ? errno : 0, + boost::asio::error::get_system_category()); + bytes_ += _error ? 0 : static_cast(its_result); + + if (_error == boost::asio::error::interrupted) + continue; + + if (_error == boost::asio::error::would_block + || _error == boost::asio::error::try_again) { + socket_.async_wait(socket_type_t::wait_read, *this); + return; + } + + if (_error) + break; + + if (bytes_ == 0) + _error = boost::asio::error::eof; + + // Extract credentials (UID/GID) + struct ucred *its_credentials; + for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&its_header); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&its_header, cmsg)) + { + if (cmsg->cmsg_level == SOL_SOCKET + && cmsg->cmsg_type == SCM_CREDENTIALS + && cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) { + + its_credentials = (struct ucred *) CMSG_DATA(cmsg); + if (its_credentials) { + uid_ = its_credentials->uid; + gid_ = its_credentials->gid; + break; + } + } + } + + break; + } + } + + // Call the handler + handler_(_error, bytes_, uid_, gid_); + } +}; + +} // namespace vsomeip + +#endif // __linux__ || ANDROID +#endif // VSOMEIP_BOOST_VERSION >= 106600 + +#endif // VSOMEIP_V3_LOCAL_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ diff --git a/implementation/endpoints/include/local_tcp_client_endpoint_impl.hpp b/implementation/endpoints/include/local_tcp_client_endpoint_impl.hpp new file mode 100644 index 0000000..45b6e72 --- /dev/null +++ b/implementation/endpoints/include/local_tcp_client_endpoint_impl.hpp @@ -0,0 +1,74 @@ +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_LOCAL_TCP_CLIENT_ENDPOINT_IMPL_HPP_ +#define VSOMEIP_V3_LOCAL_TCP_CLIENT_ENDPOINT_IMPL_HPP_ + +#include + +#include + +#include "client_endpoint_impl.hpp" + +namespace vsomeip_v3 { + +using local_tcp_client_endpoint_base_impl = client_endpoint_impl; + +class local_tcp_client_endpoint_impl: public local_tcp_client_endpoint_base_impl { +public: + local_tcp_client_endpoint_impl(const std::shared_ptr &_endpoint_host, + const std::shared_ptr &_routing_host, + const endpoint_type &_local, + const endpoint_type &_remote, + boost::asio::io_context &_io, + const std::shared_ptr &_configuration); + + virtual ~local_tcp_client_endpoint_impl(); + + void start(); + void stop(); + + bool is_local() const; + + bool get_remote_address(boost::asio::ip::address &_address) const; + std::uint16_t get_remote_port() const; + + void restart(bool _force); + void print_status(); + + bool is_reliable() const; + + // this overrides client_endpoint_impl::send to disable the pull method + // for local communication + bool send(const uint8_t *_data, uint32_t _size); + void get_configured_times_from_endpoint( + service_t _service, method_t _method, + std::chrono::nanoseconds *_debouncing, + std::chrono::nanoseconds *_maximum_retention) const; +private: + void send_queued(std::pair &_entry); + + void send_magic_cookie(); + + void connect(); + void receive(); + void receive_cbk(boost::system::error_code const &_error, + std::size_t _bytes); + void set_local_port(); + std::string get_remote_information() const; + bool check_packetizer_space(std::uint32_t _size); + bool tp_segmentation_enabled(service_t _service, method_t _method) const; + std::uint32_t get_max_allowed_reconnects() const; + void max_allowed_reconnects_reached(); + + message_buffer_t recv_buffer_; + + // send data + message_buffer_ptr_t send_data_buffer_; +}; + +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_LOCAL_TCP_CLIENT_ENDPOINT_IMPL_HPP_ diff --git a/implementation/endpoints/include/local_tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/local_tcp_server_endpoint_impl.hpp new file mode 100644 index 0000000..d4b27c3 --- /dev/null +++ b/implementation/endpoints/include/local_tcp_server_endpoint_impl.hpp @@ -0,0 +1,166 @@ +// Copyright (C) 2014-2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_LOCAL_TCP_SERVER_ENDPOINT_IMPL_HPP_ +#define VSOMEIP_V3_LOCAL_TCP_SERVER_ENDPOINT_IMPL_HPP_ + +#include +#include +#include +#include + +#include + +#include + +#include "buffer.hpp" +#include "server_endpoint_impl.hpp" + +namespace vsomeip_v3 { + +using local_tcp_server_endpoint_base_impl = server_endpoint_impl; + +class local_tcp_server_endpoint_impl + : public local_tcp_server_endpoint_base_impl { + +public: + local_tcp_server_endpoint_impl(const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + const endpoint_type& _local, + boost::asio::io_context &_io, + const std::shared_ptr& _configuration, + bool _is_routing_endpoint); + + virtual ~local_tcp_server_endpoint_impl(); + + void start(); + void stop(); + + void receive(); + + // this overrides server_endpoint_impl::send to disable the nPDU feature + // for local communication + bool send(const uint8_t *_data, uint32_t _size); + bool send_to(const std::shared_ptr, + const byte_t *_data, uint32_t _size); + bool send_error(const std::shared_ptr _target, + const byte_t *_data, uint32_t _size); + bool send_queued(const target_data_iterator_type _queue_iterator); + void get_configured_times_from_endpoint( + service_t _service, method_t _method, + std::chrono::nanoseconds *_debouncing, + std::chrono::nanoseconds *_maximum_retention) const; + + bool get_default_target(service_t, endpoint_type &) const; + + bool is_local() const; + + void accept_client_func(); + void print_status(); + + bool is_reliable() const; + std::uint16_t get_local_port() const; + void set_local_port(std::uint16_t _port); + + client_t assign_client(const byte_t *_data, uint32_t _size); + +private: + class connection: public std::enable_shared_from_this { + + public: + using ptr = std::shared_ptr; + + static ptr create(const std::shared_ptr& _server, + std::uint32_t _max_message_size, + std::uint32_t _buffer_shrink_threshold, + boost::asio::io_context &_io); + socket_type & get_socket(); + std::unique_lock get_socket_lock(); + + void start(); + void stop(); + + + void send_queued(const message_buffer_ptr_t& _buffer); + + void set_bound_client(client_t _client); + client_t get_bound_client() const; + + void set_bound_client_host(const std::string &_bound_client_host); + std::string get_bound_client_host() const; + + std::size_t get_recv_buffer_capacity() const; + + private: + connection(const std::shared_ptr& _server, + std::uint32_t _max_message_size, + std::uint32_t _initial_recv_buffer_size, + std::uint32_t _buffer_shrink_threshold, + boost::asio::io_context &_io); + + void send_cbk(const message_buffer_ptr_t _buffer, + boost::system::error_code const &_error, std::size_t _bytes); + void receive_cbk(boost::system::error_code const &_error, + std::size_t _bytes); + void calculate_shrink_count(); + std::string get_path_local() const; + std::string get_path_remote() const; + void handle_recv_buffer_exception(const std::exception &_e); + + std::mutex socket_mutex_; + local_tcp_server_endpoint_impl::socket_type socket_; + std::weak_ptr server_; + + const std::uint32_t recv_buffer_size_initial_; + const std::uint32_t max_message_size_; + + message_buffer_t recv_buffer_; + size_t recv_buffer_size_; + std::uint32_t missing_capacity_; + std::uint32_t shrink_count_; + const std::uint32_t buffer_shrink_threshold_; + + client_t bound_client_; + std::string bound_client_host_; + + vsomeip_sec_client_t sec_client_; + + bool assigned_client_; + }; + + std::mutex acceptor_mutex_; + boost::asio::ip::tcp::acceptor acceptor_; + + using connections_t = std::map; + std::mutex connections_mutex_; + connections_t connections_; + + const std::uint32_t buffer_shrink_threshold_; + + port_t local_port_; + + const bool is_routing_endpoint_; + +private: + bool add_connection(const client_t &_client, + const std::shared_ptr &_connection); + void remove_connection(const client_t &_client); + void accept_cbk(const connection::ptr& _connection, + boost::system::error_code const &_error); + std::string get_remote_information( + const target_data_iterator_type _queue_iterator) const; + std::string get_remote_information( + const endpoint_type& _remote) const; + + bool check_packetizer_space(target_data_iterator_type _queue_iterator, + message_buffer_ptr_t* _packetizer, + std::uint32_t _size); + bool tp_segmentation_enabled(service_t _service, method_t _method) const; + void send_client_identifier(const client_t &_client); +}; + +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_LOCAL_TCP_SERVER_ENDPOINT_IMPL_HPP_ diff --git a/implementation/endpoints/include/local_uds_client_endpoint_impl.hpp b/implementation/endpoints/include/local_uds_client_endpoint_impl.hpp new file mode 100644 index 0000000..74ba316 --- /dev/null +++ b/implementation/endpoints/include/local_uds_client_endpoint_impl.hpp @@ -0,0 +1,73 @@ +// Copyright (C) 2014-2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_LOCAL_UDS_CLIENT_ENDPOINT_IMPL_HPP_ +#define VSOMEIP_V3_LOCAL_UDS_CLIENT_ENDPOINT_IMPL_HPP_ + +#include + +#include + +#include "client_endpoint_impl.hpp" + +namespace vsomeip_v3 { + +using local_uds_client_endpoint_base_impl = + client_endpoint_impl; + +class local_uds_client_endpoint_impl: public local_uds_client_endpoint_base_impl { +public: + local_uds_client_endpoint_impl(const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + const endpoint_type& _remote, + boost::asio::io_context &_io, + const std::shared_ptr& _configuration); + virtual ~local_uds_client_endpoint_impl(); + + void start(); + void stop(); + + bool is_local() const; + + bool get_remote_address(boost::asio::ip::address &_address) const; + std::uint16_t get_remote_port() const; + + void restart(bool _force); + void print_status(); + + bool is_reliable() const; + + // this overrides client_endpoint_impl::send to disable the pull method + // for local communication + bool send(const uint8_t *_data, uint32_t _size); + void get_configured_times_from_endpoint( + service_t _service, method_t _method, + std::chrono::nanoseconds *_debouncing, + std::chrono::nanoseconds *_maximum_retention) const; +private: + void send_queued(std::pair &_entry); + + void send_magic_cookie(); + + void connect(); + void receive(); + void receive_cbk(boost::system::error_code const &_error, + std::size_t _bytes); + void set_local_port(); + std::string get_remote_information() const; + bool check_packetizer_space(std::uint32_t _size); + bool tp_segmentation_enabled(service_t _service, method_t _method) const; + std::uint32_t get_max_allowed_reconnects() const; + void max_allowed_reconnects_reached(); + + message_buffer_t recv_buffer_; + + // send data + message_buffer_ptr_t send_data_buffer_; +}; + +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_LOCAL_UDS_CLIENT_ENDPOINT_IMPL_HPP_ diff --git a/implementation/endpoints/include/local_uds_server_endpoint_impl.hpp b/implementation/endpoints/include/local_uds_server_endpoint_impl.hpp new file mode 100644 index 0000000..256d866 --- /dev/null +++ b/implementation/endpoints/include/local_uds_server_endpoint_impl.hpp @@ -0,0 +1,191 @@ +// Copyright (C) 2014-2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_LOCAL_UDS_SERVER_ENDPOINT_IMPL_HPP_ +#define VSOMEIP_V3_LOCAL_UDS_SERVER_ENDPOINT_IMPL_HPP_ + +#include +#include +#include +#include + +#if VSOMEIP_BOOST_VERSION < 106600 +# include +#else +# include +#endif + +#include +#include + +#include "buffer.hpp" +#include "server_endpoint_impl.hpp" + +namespace vsomeip_v3 { + +using local_uds_server_endpoint_base_impl = server_endpoint_impl< +#if VSOMEIP_BOOST_VERSION < 106600 + boost::asio::local::stream_protocol_ext +#else + boost::asio::local::stream_protocol +#endif + >; + +class local_uds_server_endpoint_impl: public local_uds_server_endpoint_base_impl { +public: + local_uds_server_endpoint_impl(const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + const endpoint_type& _local, + boost::asio::io_context &_io, + const std::shared_ptr& _configuration, + bool _is_routing_endpoint); + + local_uds_server_endpoint_impl(const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + const endpoint_type& _local, + boost::asio::io_context &_io, + int native_socket, + const std::shared_ptr& _configuration, + bool _is_routing_endpoint); + + virtual ~local_uds_server_endpoint_impl(); + + void start(); + void stop(); + + void receive(); + + // this overrides server_endpoint_impl::send to disable the nPDU feature + // for local communication + bool send(const uint8_t *_data, uint32_t _size); + bool send_to(const std::shared_ptr, + const byte_t *_data, uint32_t _size); + bool send_error(const std::shared_ptr _target, + const byte_t *_data, uint32_t _size); + bool send_queued(const target_data_iterator_type _queue_iterator); + void get_configured_times_from_endpoint( + service_t _service, method_t _method, + std::chrono::nanoseconds *_debouncing, + std::chrono::nanoseconds *_maximum_retention) const; + + bool get_default_target(service_t, endpoint_type &) const; + + bool is_local() const; + + void accept_client_func(); + void print_status(); + + bool is_reliable() const; + std::uint16_t get_local_port() const; + void set_local_port(std::uint16_t _port); + + client_t assign_client(const byte_t *_data, uint32_t _size); + +private: + class connection: public std::enable_shared_from_this { + + public: + using ptr = std::shared_ptr; + + static ptr create(const std::shared_ptr& _server, + std::uint32_t _max_message_size, + std::uint32_t _buffer_shrink_threshold, + boost::asio::io_context &_io); + socket_type & get_socket(); + std::unique_lock get_socket_lock(); + + void start(); + void stop(); + + void send_queued(const message_buffer_ptr_t& _buffer); + + void set_bound_client(client_t _client); + client_t get_bound_client() const; + + void set_bound_client_host(const std::string &_bound_client_host); + std::string get_bound_client_host() const; + +#if defined(__linux__) || defined(ANDROID) + void set_bound_sec_client(const vsomeip_sec_client_t &_sec_client); +#endif + + std::size_t get_recv_buffer_capacity() const; + + private: + connection(const std::shared_ptr& _server, + std::uint32_t _max_message_size, + std::uint32_t _initial_recv_buffer_size, + std::uint32_t _buffer_shrink_threshold, + boost::asio::io_context &_io); + + void send_cbk(const message_buffer_ptr_t _buffer, + boost::system::error_code const &_error, std::size_t _bytes); + void receive_cbk(boost::system::error_code const &_error, + std::size_t _bytes +#if defined(__linux__) || defined(ANDROID) + , std::uint32_t const &_uid, std::uint32_t const &_gid +#endif + ); + void calculate_shrink_count(); + std::string get_path_local() const; + std::string get_path_remote() const; + void handle_recv_buffer_exception(const std::exception &_e); + + std::mutex socket_mutex_; + local_uds_server_endpoint_impl::socket_type socket_; + std::weak_ptr server_; + + const std::uint32_t recv_buffer_size_initial_; + const std::uint32_t max_message_size_; + + message_buffer_t recv_buffer_; + size_t recv_buffer_size_; + std::uint32_t missing_capacity_; + std::uint32_t shrink_count_; + const std::uint32_t buffer_shrink_threshold_; + + client_t bound_client_; + std::string bound_client_host_; + + vsomeip_sec_client_t sec_client_; + + bool assigned_client_; + }; + + std::mutex acceptor_mutex_; +#if VSOMEIP_BOOST_VERSION < 106600 + boost::asio::local::stream_protocol_ext::acceptor acceptor_; +#else + boost::asio::local::stream_protocol::acceptor acceptor_; +#endif + using connections_t = std::map; + std::mutex connections_mutex_; + connections_t connections_; + + const std::uint32_t buffer_shrink_threshold_; + + const bool is_routing_endpoint_; + +private: + bool add_connection(const client_t &_client, + const std::shared_ptr &_connection); + void remove_connection(const client_t &_client); + void accept_cbk(const connection::ptr& _connection, + boost::system::error_code const &_error); + std::string get_remote_information( + const target_data_iterator_type _queue_iterator) const; + std::string get_remote_information( + const endpoint_type& _remote) const; + + bool check_packetizer_space(target_data_iterator_type _queue_iterator, + message_buffer_ptr_t* _packetizer, + std::uint32_t _size); + bool tp_segmentation_enabled(service_t _service, method_t _method) const; + void send_client_identifier(const client_t &_client); +}; + +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_LOCAL_UDS_SERVER_ENDPOINT_IMPL_HPP_ diff --git a/implementation/endpoints/include/netlink_connector.hpp b/implementation/endpoints/include/netlink_connector.hpp index bb484b8..0a7c94e 100644 --- a/implementation/endpoints/include/netlink_connector.hpp +++ b/implementation/endpoints/include/netlink_connector.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,7 +6,7 @@ #ifndef VSOMEIP_V3_NETLINK_CONNECTOR_HPP_ #define VSOMEIP_V3_NETLINK_CONNECTOR_HPP_ -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #include @@ -15,7 +15,6 @@ #include #include -#include #include #include @@ -27,23 +26,23 @@ template class nl_endpoint { public: /// The protocol type associated with the endpoint. - typedef Protocol protocol_type; - typedef boost::asio::detail::socket_addr_type data_type; + using protocol_type = Protocol; + using data_type = boost::asio::detail::socket_addr_type; /// Default constructor. nl_endpoint() { sockaddr.nl_family = PF_NETLINK; sockaddr.nl_groups = 0; - sockaddr.nl_pid = static_cast(getpid()); + sockaddr.nl_pid = 0; // Let the kernel do the assignment } /// Construct an endpoint using the specified path name. - nl_endpoint(int group, int pid=getpid()) + nl_endpoint(int group) { sockaddr.nl_family = PF_NETLINK; sockaddr.nl_groups = static_cast(group); - sockaddr.nl_pid = static_cast(pid); + sockaddr.nl_pid = 0; } /// Copy constructor. @@ -124,25 +123,31 @@ public: return PF_NETLINK; } - typedef nl_endpoint endpoint; - typedef boost::asio::basic_raw_socket socket; + using endpoint = nl_endpoint; + using socket = boost::asio::basic_raw_socket; private: int proto; }; -typedef std::function< void (bool, std::string, bool) > net_if_changed_handler_t; +using net_if_changed_handler_t = std::function< void ( + bool, // true = is interface, false = is route + std::string, // interface name + bool) // available? +>; class netlink_connector : public std::enable_shared_from_this { public: - netlink_connector(boost::asio::io_service& _io, boost::asio::ip::address _address, - boost::asio::ip::address _multicast_address): + netlink_connector(boost::asio::io_context &_io, const boost::asio::ip::address &_address, + const boost::asio::ip::address &_multicast_address, + bool _is_requiring_link = true): net_if_index_for_address_(0), handler_(nullptr), socket_(_io), recv_buffer_(recv_buffer_size, 0), address_(_address), - multicast_address_(_multicast_address) { + multicast_address_(_multicast_address), + is_requiring_link_(_is_requiring_link) { } ~netlink_connector() {} @@ -180,10 +185,11 @@ private: boost::asio::ip::address address_; boost::asio::ip::address multicast_address_; + bool is_requiring_link_; }; } // namespace vsomeip_v3 -#endif // NOT _WIN32 +#endif // __linux__ || ANDROID #endif // VSOMEIP_V3_NETLINK_CONNECTOR_HPP_ diff --git a/implementation/endpoints/include/server_endpoint_impl.hpp b/implementation/endpoints/include/server_endpoint_impl.hpp index dfa22e6..b7ee74d 100644 --- a/implementation/endpoints/include/server_endpoint_impl.hpp +++ b/implementation/endpoints/include/server_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -14,7 +14,6 @@ #include #include -#include #include "buffer.hpp" #include "endpoint_impl.hpp" @@ -26,14 +25,33 @@ template class server_endpoint_impl: public endpoint_impl, public std::enable_shared_from_this > { public: - typedef typename Protocol::socket socket_type; - typedef typename Protocol::endpoint endpoint_type; - typedef typename std::map>> queue_type; - typedef typename queue_type::iterator queue_iterator_type; + using socket_type = typename Protocol::socket; + using endpoint_type = typename Protocol::endpoint; + struct endpoint_data_type { + endpoint_data_type(boost::asio::io_context &_io) + : train_(std::make_shared()), + dispatch_timer_(std::make_shared(_io)), + has_last_departure_(false), + queue_size_(0) { + } + + std::shared_ptr train_; + std::map > > dispatched_trains_; + std::shared_ptr dispatch_timer_; + std::chrono::steady_clock::time_point last_departure_; + bool has_last_departure_; + + std::deque > queue_; + std::size_t queue_size_; + }; + + using target_data_type = typename std::map; + using target_data_iterator_type = typename target_data_type::iterator; server_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, - endpoint_type _local, boost::asio::io_service &_io, + endpoint_type _local, boost::asio::io_context &_io, std::uint32_t _max_message_size, configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration); @@ -49,11 +67,10 @@ public: bool send(const std::vector& _cmd_header, const byte_t *_data, uint32_t _size); - void prepare_stop(endpoint::prepare_stop_handler_t _handler, + void prepare_stop(const endpoint::prepare_stop_handler_t &_handler, service_t _service); virtual void stop(); - bool flush(endpoint_type _target, - const std::shared_ptr& _train); + bool flush(target_data_iterator_type _it); size_t get_queue_size() const; @@ -63,16 +80,15 @@ public: public: void connect_cbk(boost::system::error_code const &_error); - void send_cbk(const queue_iterator_type _queue_iterator, + void send_cbk(const target_data_iterator_type _it, boost::system::error_code const &_error, std::size_t _bytes); - void flush_cbk(endpoint_type _target, - const std::shared_ptr& _train, - const boost::system::error_code &_error_code); + void flush_cbk(target_data_iterator_type _it, + const boost::system::error_code &_error_code); protected: virtual bool send_intern(endpoint_type _target, const byte_t *_data, uint32_t _port); - virtual void send_queued(const queue_iterator_type _queue_iterator) = 0; + virtual bool send_queued(const target_data_iterator_type _it) = 0; virtual void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, @@ -85,26 +101,23 @@ protected: typename endpoint_impl::cms_ret_e check_message_size( const std::uint8_t * const _data, std::uint32_t _size, - const endpoint_type& _target); + const endpoint_type &_target); bool check_queue_limit(const uint8_t *_data, std::uint32_t _size, std::size_t _current_queue_size) const; - void queue_train(const queue_iterator_type _queue_iterator, - const std::shared_ptr& _train, - bool _queue_size_zero_on_entry); - queue_iterator_type find_or_create_queue_unlocked(const endpoint_type& _target); - std::shared_ptr find_or_create_train_unlocked(const endpoint_type& _target); + bool queue_train(const target_data_iterator_type _it, + const std::shared_ptr &_train, + bool _queue_size_zero_on_entry); - void send_segments(const tp::tp_split_messages_t &_segments, const endpoint_type &_target); + void send_segments(const tp::tp_split_messages_t &_segments, + std::uint32_t _separation_time, const endpoint_type &_target); -protected: - queue_type queues_; + target_data_iterator_type find_or_create_target_unlocked(endpoint_type _target); - std::mutex requests_mutex_; - std::map, endpoint_type> - > requests_; +protected: + std::mutex clients_mutex_; + std::map > clients_; - std::map> trains_; + target_data_type targets_; std::map prepare_stop_handlers_; @@ -116,12 +129,18 @@ protected: private: virtual std::string get_remote_information( - const queue_iterator_type _queue_iterator) const = 0; + const target_data_iterator_type _queue_iterator) const = 0; virtual std::string get_remote_information( const endpoint_type& _remote) const = 0; virtual bool tp_segmentation_enabled(service_t _service, method_t _method) const = 0; - void wait_until_debounce_time_reached(const std::shared_ptr& _train) const; + + void schedule_train(endpoint_data_type &_target); + void update_last_departure(endpoint_data_type &_data); + + void start_dispatch_timer(target_data_iterator_type _it, + const std::chrono::steady_clock::time_point &_now); + void cancel_dispatch_timer(target_data_iterator_type _it); }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp index 137571c..8a314bc 100644 --- a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -16,9 +16,8 @@ namespace vsomeip_v3 { -typedef client_endpoint_impl< - boost::asio::ip::tcp - > tcp_client_endpoint_base_impl; +using tcp_client_endpoint_base_impl = + client_endpoint_impl; class tcp_client_endpoint_impl: public tcp_client_endpoint_base_impl { public: @@ -26,7 +25,7 @@ public: const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration); virtual ~tcp_client_endpoint_impl(); @@ -42,7 +41,7 @@ public: void send_cbk(boost::system::error_code const &_error, std::size_t _bytes, const message_buffer_ptr_t& _sent_msg); private: - void send_queued(message_buffer_ptr_t _buffer); + void send_queued(std::pair &_entry); void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, @@ -63,8 +62,8 @@ private: std::size_t _missing_capacity); void calculate_shrink_count(const message_buffer_ptr_t& _recv_buffer, std::size_t _recv_buffer_size); - const std::string get_address_port_remote() const; - const std::string get_address_port_local() const; + std::string get_address_port_remote() const; + std::string get_address_port_local() const; void handle_recv_buffer_exception(const std::exception &_e, const message_buffer_ptr_t& _recv_buffer, std::size_t _recv_buffer_size); diff --git a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp index bf0e1b9..1a2cf4e 100644 --- a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,9 +19,8 @@ namespace vsomeip_v3 { -typedef server_endpoint_impl< - boost::asio::ip::tcp - > tcp_server_endpoint_base_impl; +using tcp_server_endpoint_base_impl = + server_endpoint_impl; class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl { @@ -29,7 +28,7 @@ public: tcp_server_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration); virtual ~tcp_server_endpoint_impl(); @@ -40,14 +39,14 @@ public: const byte_t *_data, uint32_t _size); bool send_error(const std::shared_ptr _target, const byte_t *_data, uint32_t _size); - void send_queued(const queue_iterator_type _queue_iterator); - void send_queued_sync(const queue_iterator_type _queue_iterator); + bool send_queued(const target_data_iterator_type _it); + void send_queued_sync(const target_data_iterator_type _it); void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, std::chrono::nanoseconds *_maximum_retention) const; - VSOMEIP_EXPORT bool is_established(const std::shared_ptr& _endpoint); + VSOMEIP_EXPORT bool is_established_to(const std::shared_ptr& _endpoint); bool get_default_target(service_t, endpoint_type &) const; @@ -64,14 +63,17 @@ private: class connection: public std::enable_shared_from_this { public: - typedef std::shared_ptr ptr; + using ptr = std::shared_ptr; static ptr create(const std::weak_ptr& _server, std::uint32_t _max_message_size, std::uint32_t _buffer_shrink_threshold, bool _magic_cookies_enabled, - boost::asio::io_service & _io_service, + boost::asio::io_context & _io, std::chrono::milliseconds _send_timeout); + + ~connection(); + socket_type & get_socket(); std::unique_lock get_socket_lock(); @@ -79,11 +81,11 @@ private: void stop(); void receive(); - void send_queued(const queue_iterator_type _queue_iterator); - void send_queued_sync(const queue_iterator_type _queue_iterator); + void send_queued(const target_data_iterator_type _it); + void send_queued_sync(const target_data_iterator_type _it); void set_remote_info(const endpoint_type &_remote); - const std::string get_address_port_remote() const; + std::string get_address_port_remote() const; std::size_t get_recv_buffer_capacity() const; private: @@ -92,14 +94,14 @@ private: std::uint32_t _recv_buffer_size_initial, std::uint32_t _buffer_shrink_threshold, bool _magic_cookies_enabled, - boost::asio::io_service & _io_service, + boost::asio::io_context &_io, std::chrono::milliseconds _send_timeout); bool send_magic_cookie(message_buffer_ptr_t &_buffer); bool is_magic_cookie(size_t _offset) const; void receive_cbk(boost::system::error_code const &_error, std::size_t _bytes); void calculate_shrink_count(); - const std::string get_address_port_local() const; + std::string get_address_port_local() const; void handle_recv_buffer_exception(const std::exception &_e); std::size_t write_completion_condition( const boost::system::error_code& _error, @@ -134,7 +136,7 @@ private: std::mutex acceptor_mutex_; boost::asio::ip::tcp::acceptor acceptor_; std::mutex connections_mutex_; - typedef std::map connections_t; + using connections_t = std::map; connections_t connections_; const std::uint32_t buffer_shrink_threshold_; const std::uint16_t local_port_; @@ -145,7 +147,7 @@ private: void accept_cbk(const connection::ptr& _connection, boost::system::error_code const &_error); std::string get_remote_information( - const queue_iterator_type _queue_iterator) const; + const target_data_iterator_type _it) const; std::string get_remote_information(const endpoint_type& _remote) const; bool tp_segmentation_enabled(service_t _service, method_t _method) const; }; diff --git a/implementation/endpoints/include/tp.hpp b/implementation/endpoints/include/tp.hpp index 0e3a9d0..ec185b2 100644 --- a/implementation/endpoints/include/tp.hpp +++ b/implementation/endpoints/include/tp.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -24,9 +24,9 @@ namespace tp { #define VSOMEIP_TP_PAYLOAD_POS 20 // 28 bit length + 3 bit reserved + 1 bit more segments -typedef std::uint32_t tp_header_t; -typedef std::uint8_t tp_message_type_t; -typedef std::vector tp_split_messages_t; +using tp_header_t = std::uint32_t; +using tp_message_type_t = std::uint8_t; +using tp_split_messages_t = std::vector; const std::uint8_t TP_FLAG = 0x20; @@ -49,9 +49,10 @@ public: } static tp_split_messages_t tp_split_message( - const std::uint8_t * const _data, std::uint32_t _size); + const std::uint8_t * const _data, std::uint32_t _size, + std::uint16_t _max_segment_length); - static const std::uint16_t tp_max_segment_length_; + static const std::uint16_t tp_max_segment_length_ = 1392; }; } // namespace tp diff --git a/implementation/endpoints/include/tp_message.hpp b/implementation/endpoints/include/tp_message.hpp index 269a1f1..13aef2d 100644 --- a/implementation/endpoints/include/tp_message.hpp +++ b/implementation/endpoints/include/tp_message.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/endpoints/include/tp_reassembler.hpp b/implementation/endpoints/include/tp_reassembler.hpp index aaf61c5..5e50c8c 100644 --- a/implementation/endpoints/include/tp_reassembler.hpp +++ b/implementation/endpoints/include/tp_reassembler.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,8 +11,13 @@ #include #include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include -#include #include #include @@ -25,7 +30,7 @@ namespace tp { class tp_reassembler : public std::enable_shared_from_this { public: - tp_reassembler(std::uint32_t _max_message_size, boost::asio::io_service &_io); + tp_reassembler(std::uint32_t _max_message_size, boost::asio::io_context &_io); /** * @return Returns a pair consisting of a bool and a message_buffer_t. The * value of the bool is set to true if the pair contains a finished message diff --git a/implementation/endpoints/include/udp_client_endpoint_impl.hpp b/implementation/endpoints/include/udp_client_endpoint_impl.hpp index 3a3fdcb..56fcc20 100644 --- a/implementation/endpoints/include/udp_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_client_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,7 +8,6 @@ #include -#include #include #include @@ -21,9 +20,8 @@ namespace vsomeip_v3 { class endpoint_adapter; -typedef client_endpoint_impl< - boost::asio::ip::udp - > udp_client_endpoint_base_impl; +using udp_client_endpoint_base_impl = + client_endpoint_impl; class udp_client_endpoint_impl: virtual public udp_client_endpoint_base_impl { @@ -32,7 +30,7 @@ public: const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration); virtual ~udp_client_endpoint_impl(); @@ -48,10 +46,10 @@ public: void print_status(); bool is_reliable() const; - void send_cbk(boost::system::error_code const &_error, std::size_t _bytes, - const message_buffer_ptr_t &_sent_msg); + void send_cbk(boost::system::error_code const &_error, + std::size_t _bytes, const message_buffer_ptr_t &_sent_msg); private: - void send_queued(message_buffer_ptr_t _buffer); + void send_queued(std::pair &_entry); void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, @@ -59,8 +57,8 @@ private: void connect(); void receive(); void set_local_port(); - const std::string get_address_port_remote() const; - const std::string get_address_port_local() const; + std::string get_address_port_remote() const; + std::string get_address_port_local() const; std::string get_remote_information() const; bool tp_segmentation_enabled(service_t _service, method_t _method) const; std::uint32_t get_max_allowed_reconnects() const; @@ -69,7 +67,7 @@ private: private: const boost::asio::ip::address remote_address_; const std::uint16_t remote_port_; - int udp_receive_buffer_size_; + const int udp_receive_buffer_size_; std::shared_ptr tp_reassembler_; }; diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp index fef09dc..dd7e224 100644 --- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,10 +6,11 @@ #ifndef VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_HPP_ #define VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_HPP_ -#include +#if VSOMEIP_BOOST_VERSION < 106600 #include - -#include +#else +#include +#endif #include @@ -18,9 +19,13 @@ namespace vsomeip_v3 { -typedef server_endpoint_impl< - boost::asio::ip::udp_ext - > udp_server_endpoint_base_impl; +#if VSOMEIP_BOOST_VERSION < 106600 +using udp_server_endpoint_base_impl = + server_endpoint_impl; +#else +using udp_server_endpoint_base_impl = + server_endpoint_impl; +#endif class udp_server_endpoint_impl: public udp_server_endpoint_base_impl { @@ -28,7 +33,7 @@ public: udp_server_endpoint_impl(const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration); virtual ~udp_server_endpoint_impl(); @@ -41,7 +46,7 @@ public: const byte_t *_data, uint32_t _size); bool send_error(const std::shared_ptr _target, const byte_t *_data, uint32_t _size); - void send_queued(const queue_iterator_type _queue_iterator); + bool send_queued(const target_data_iterator_type _it); void get_configured_times_from_endpoint( service_t _service, method_t _method, std::chrono::nanoseconds *_debouncing, @@ -49,7 +54,9 @@ public: VSOMEIP_EXPORT void join(const std::string &_address); VSOMEIP_EXPORT void join_unlocked(const std::string &_address); - void leave(const std::string &_address); + VSOMEIP_EXPORT void leave(const std::string &_address); + VSOMEIP_EXPORT void set_multicast_option( + const boost::asio::ip::address &_address, bool _is_join); void add_default_target(service_t _service, const std::string &_address, uint16_t _port); @@ -71,33 +78,35 @@ private: bool is_joined(const std::string &_address) const; bool is_joined(const std::string &_address, bool* _received) const; std::string get_remote_information( - const queue_iterator_type _queue_iterator) const; + const target_data_iterator_type _it) const; std::string get_remote_information(const endpoint_type& _remote) const; - const std::string get_address_port_local() const; + std::string get_address_port_local() const; bool tp_segmentation_enabled(service_t _service, method_t _method) const; void on_unicast_received(boost::system::error_code const &_error, - std::size_t _bytes, - boost::asio::ip::address const &_destination); + std::size_t _bytes); void on_multicast_received(boost::system::error_code const &_error, - std::size_t _bytes, - boost::asio::ip::address const &_destination, - uint8_t _multicast_id); + std::size_t _bytes, uint8_t _multicast_id, + const boost::asio::ip::address &_destination); void on_message_received(boost::system::error_code const &_error, std::size_t _bytes, - boost::asio::ip::address const &_destination, + bool _is_multicast, endpoint_type const &_remote, message_buffer_t const &_buffer); + bool is_same_subnet(const boost::asio::ip::address &_address) const; + private: socket_type unicast_socket_; endpoint_type unicast_remote_; message_buffer_t unicast_recv_buffer_; mutable std::mutex unicast_mutex_; + bool is_v4_; + std::unique_ptr multicast_socket_; std::unique_ptr multicast_local_; endpoint_type multicast_remote_; @@ -110,6 +119,9 @@ private: mutable std::mutex default_targets_mutex_; std::map default_targets_; + boost::asio::ip::address netmask_; + unsigned short prefix_; + const std::uint16_t local_port_; std::shared_ptr tp_reassembler_; diff --git a/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp b/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp new file mode 100644 index 0000000..71fad4d --- /dev/null +++ b/implementation/endpoints/include/udp_server_endpoint_impl_receive_op.hpp @@ -0,0 +1,186 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ +#define VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ + +#if VSOMEIP_BOOST_VERSION >= 106600 +#if defined(__linux__) || defined(ANDROID) + +#include + +#include + +#include + +namespace vsomeip_v3 { + +struct udp_server_endpoint_impl_receive_op { + + using socket_type_t = boost::asio::ip::udp::socket; + using endpoint_type_t = boost::asio::ip::udp::endpoint; + using receive_handler_t = + std::function; + + socket_type_t &socket_; + endpoint_type_t &sender_; + receive_handler_t handler_; + byte_t *buffer_; + size_t length_; + uint8_t multicast_id_; + bool is_v4_; + boost::asio::ip::address destination_; + size_t bytes_; + + void operator()(boost::system::error_code _error) { + + sender_ = endpoint_type_t(); // reset + + if (!_error) { + + if (!socket_.native_non_blocking()) + socket_.native_non_blocking(true, _error); + + for (;;) { + ssize_t its_result; + int its_flags(0); + + // Create control elements + msghdr its_header = msghdr(); + struct iovec its_vec[1]; + + // Prepare + its_vec[0].iov_base = buffer_; + its_vec[0].iov_len = length_; + + // Add io buffer + its_header.msg_iov = its_vec; + its_header.msg_iovlen = 1; + + // Sender & destination address info + union { + struct sockaddr_in v4; + struct sockaddr_in6 v6; + } addr; + + union { + struct cmsghdr cmh; + union { + char v4[CMSG_SPACE(sizeof(struct in_pktinfo))]; + char v6[CMSG_SPACE(sizeof(struct in6_pktinfo))]; + } control; + } control_un; + + // Prepare + if (is_v4_) { + its_header.msg_name = &addr; + its_header.msg_namelen = sizeof(sockaddr_in); + + its_header.msg_control = control_un.control.v4; + its_header.msg_controllen = sizeof(control_un.control.v4); + } else { + its_header.msg_name = &addr; + its_header.msg_namelen = sizeof(sockaddr_in6); + + its_header.msg_control = control_un.control.v6; + its_header.msg_controllen = sizeof(control_un.control.v6); + } + + // Call recvmsg and handle its result + errno = 0; + its_result = ::recvmsg(socket_.native_handle(), &its_header, its_flags); + + _error = boost::system::error_code(its_result < 0 ? errno : 0, + boost::asio::error::get_system_category()); + bytes_ += _error ? 0 : static_cast(its_result); + + if (_error == boost::asio::error::interrupted) + continue; + + if (_error == boost::asio::error::would_block + || _error == boost::asio::error::try_again) { + + socket_.async_wait(socket_type_t::wait_read, *this); + return; + } + + if (_error) + break; + + if (bytes_ == 0) + _error = boost::asio::error::eof; + + // Extract sender & destination addresses + if (is_v4_) { + // sender + boost::asio::ip::address_v4 its_sender_address( + ntohl(addr.v4.sin_addr.s_addr)); + in_port_t its_sender_port(ntohs(addr.v4.sin_port)); + sender_ = endpoint_type_t(its_sender_address, its_sender_port); + + // destination + struct in_pktinfo *its_pktinfo_v4; + for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&its_header); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&its_header, cmsg)) { + + if (cmsg->cmsg_level == IPPROTO_IP + && cmsg->cmsg_type == IP_PKTINFO + && cmsg->cmsg_len == CMSG_LEN(sizeof(*its_pktinfo_v4))) { + + its_pktinfo_v4 = (struct in_pktinfo*) CMSG_DATA(cmsg); + if (its_pktinfo_v4) { + destination_ = boost::asio::ip::address_v4( + ntohl(its_pktinfo_v4->ipi_addr.s_addr)); + break; + } + } + } + } else { + boost::asio::ip::address_v6::bytes_type its_bytes; + + // sender + boost::asio::ip::address_v6 its_sender_address; + for (size_t i = 0; i < its_bytes.size(); i++) + its_bytes[i] = addr.v6.sin6_addr.s6_addr[i]; + in_port_t its_sender_port(ntohs(addr.v6.sin6_port)); + sender_ = endpoint_type_t(its_sender_address, its_sender_port); + + struct in6_pktinfo *its_pktinfo_v6; + for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&its_header); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&its_header, cmsg)) { + + if (cmsg->cmsg_level == IPPROTO_IPV6 + && cmsg->cmsg_type == IPV6_PKTINFO + && cmsg->cmsg_len == CMSG_LEN(sizeof(*its_pktinfo_v6))) { + + its_pktinfo_v6 = (struct in6_pktinfo *) CMSG_DATA(cmsg); + if (its_pktinfo_v6) { + for (size_t i = 0; i < its_bytes.size(); i++) + its_bytes[i] = its_pktinfo_v6->ipi6_addr.s6_addr[i]; + destination_ = boost::asio::ip::address_v6(its_bytes); + break; + } + } + } + } + + break; + } + } + + // Call the handler + handler_(_error, bytes_, multicast_id_, destination_); + } +}; + +} // namespace vsomeip + +#endif // __linux__ || ANDROID +#endif // VSOMEIP_BOOST_VERSION >= 106600 + +#endif // VSOMEIP_V3_UDP_SERVER_ENDPOINT_IMPL_RECEIVE_OP_HPP_ diff --git a/implementation/endpoints/include/virtual_server_endpoint_impl.hpp b/implementation/endpoints/include/virtual_server_endpoint_impl.hpp index adf3972..98b3958 100644 --- a/implementation/endpoints/include/virtual_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/virtual_server_endpoint_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,7 +6,12 @@ #ifndef VSOMEIP_V3_VIRTUAL_SERVER_ENDPOINT_IMPL_HPP_ #define VSOMEIP_V3_VIRTUAL_SERVER_ENDPOINT_IMPL_HPP_ -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include @@ -20,12 +25,12 @@ public: const std::string &_address, uint16_t _port, bool _reliable, - boost::asio::io_service& _service); + boost::asio::io_context &_io); virtual ~virtual_server_endpoint_impl(); void start(); - void prepare_stop(endpoint::prepare_stop_handler_t _handler, + void prepare_stop(const endpoint::prepare_stop_handler_t &_handler, service_t _service); void stop(); @@ -35,8 +40,6 @@ public: void set_connected(bool _connected); bool send(const byte_t *_data, uint32_t _size); - bool send(const std::vector& _cmd_header, const byte_t *_data, - uint32_t _size); bool send_to(const std::shared_ptr _target, const byte_t *_data, uint32_t _size); bool send_error(const std::shared_ptr _target, @@ -61,7 +64,7 @@ public: void restart(bool _force); - void register_error_handler(error_handler_t _handler); + void register_error_handler(const error_handler_t &_handler); void print_status(); size_t get_queue_size() const; @@ -72,7 +75,7 @@ private: bool reliable_; uint32_t use_count_; - boost::asio::io_service& service_; + boost::asio::io_context &io_; }; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/client_endpoint_impl.cpp b/implementation/endpoints/src/client_endpoint_impl.cpp index 66b3138..6850f66 100644 --- a/implementation/endpoints/src/client_endpoint_impl.cpp +++ b/implementation/endpoints/src/client_endpoint_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -30,7 +30,7 @@ client_endpoint_impl::client_endpoint_impl( const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, - boost::asio::io_service &_io, + boost::asio::io_context &_io, std::uint32_t _max_message_size, configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration) @@ -41,7 +41,10 @@ client_endpoint_impl::client_endpoint_impl( connect_timeout_(VSOMEIP_DEFAULT_CONNECT_TIMEOUT), // TODO: use config variable state_(cei_state_e::CLOSED), reconnect_counter_(0), - train_(_io), + connecting_timer_(_io), connecting_timeout_(VSOMEIP_DEFAULT_CONNECTING_TIMEOUT), + train_(std::make_shared()), + dispatch_timer_(_io), + has_last_departure_(false), queue_size_(0), was_not_connected_(false), local_port_(0), @@ -50,26 +53,31 @@ client_endpoint_impl::client_endpoint_impl( template client_endpoint_impl::~client_endpoint_impl() { + } template bool client_endpoint_impl::is_client() const { + return true; } template bool client_endpoint_impl::is_established() const { + return state_ == cei_state_e::ESTABLISHED; } template bool client_endpoint_impl::is_established_or_connected() const { + return (state_ == cei_state_e::ESTABLISHED || state_ == cei_state_e::CONNECTED); } template void client_endpoint_impl::set_established(bool _established) { + if (_established) { if (state_ != cei_state_e::CONNECTING) { std::lock_guard its_lock(socket_mutex_); @@ -86,6 +94,7 @@ void client_endpoint_impl::set_established(bool _established) { template void client_endpoint_impl::set_connected(bool _connected) { + if (_connected) { std::lock_guard its_lock(socket_mutex_); if (socket_->is_open()) { @@ -100,7 +109,8 @@ void client_endpoint_impl::set_connected(bool _connected) { template void client_endpoint_impl::prepare_stop( - endpoint::prepare_stop_handler_t _handler, service_t _service) { + const endpoint::prepare_stop_handler_t &_handler, service_t _service) { + (void) _handler; (void) _service; } @@ -129,12 +139,14 @@ void client_endpoint_impl::stop() { } template -message_buffer_ptr_t client_endpoint_impl::get_front() { - message_buffer_ptr_t its_buffer; +std::pair +client_endpoint_impl::get_front() { + + std::pair its_entry; if (queue_.size()) - its_buffer = queue_.front(); + its_entry = queue_.front(); - return (its_buffer); + return (its_entry); } @@ -142,6 +154,7 @@ template bool client_endpoint_impl::send_to( const std::shared_ptr _target, const byte_t *_data, uint32_t _size) { + (void)_target; (void)_data; (void)_size; @@ -154,6 +167,7 @@ template bool client_endpoint_impl::send_error( const std::shared_ptr _target, const byte_t *_data, uint32_t _size) { + (void)_target; (void)_data; (void)_size; @@ -165,9 +179,11 @@ bool client_endpoint_impl::send_error( template bool client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { + std::lock_guard its_lock(mutex_); bool must_depart(false); - const bool queue_size_zero_on_entry(queue_.empty()); + auto its_now(std::chrono::steady_clock::now()); + #if 0 std::stringstream msg; msg << "cei::send: "; @@ -192,8 +208,8 @@ bool client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) break; } - // STEP 1: Determine elapsed time and update the departure time and cancel the departure timer - train_.update_departure_time_and_stop_departure(); + // STEP 1: Cancel dispatch timer + cancel_dispatch_timer(); // STEP 3: Get configured timings const service_t its_service = VSOMEIP_BYTES_TO_WORD( @@ -207,36 +223,36 @@ bool client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) // STEP 4: Check if the passenger enters an empty train const std::pair its_identifier = std::make_pair( its_service, its_method); - if (train_.passengers_.empty()) { - train_.departure_ = its_retention; + if (train_->passengers_.empty()) { + train_->departure_ = its_now + its_retention; // latest possible } else { // STEP 4.1: Check whether the current train already contains the message - if (train_.passengers_.end() != train_.passengers_.find(its_identifier)) { + if (train_->passengers_.end() != train_->passengers_.find(its_identifier)) { must_depart = true; } else { // STEP 5: Check whether the current message fits into the current train - if (train_.buffer_->size() + _size > endpoint_impl::max_message_size_) { + if (train_->buffer_->size() + _size > endpoint_impl::max_message_size_) { must_depart = true; } else { // STEP 6: Check debouncing time - if (its_debouncing > train_.minimal_max_retention_time_) { + if (its_debouncing > train_->minimal_max_retention_time_) { // train's latest departure would already undershot new // passenger's debounce time must_depart = true; } else { - if (its_debouncing > train_.departure_) { + if (its_now + its_debouncing > train_->departure_) { // train departs earlier as the new passenger's debounce // time allows must_depart = true; } else { // STEP 7: Check maximum retention time - if (its_retention < train_.minimal_debounce_time_) { + if (its_retention < train_->minimal_debounce_time_) { // train's earliest departure would already exceed // the new passenger's retention time. must_depart = true; } else { - if (its_retention < train_.departure_) { - train_.departure_ = its_retention; + if (its_now + its_retention < train_->departure_) { + train_->departure_ = its_now + its_retention; } } } @@ -248,50 +264,40 @@ bool client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) // STEP 8: if necessary, send current buffer and create a new one if (must_depart) { // STEP 8.1: check if debounce time would be undershot here if the train - // departs. Block sending until train is allowed to depart. - wait_until_debounce_time_reached(); - train_.passengers_.clear(); - queue_train(queue_size_zero_on_entry); - train_.last_departure_ = std::chrono::steady_clock::now(); - train_.departure_ = its_retention; - train_.minimal_debounce_time_ = std::chrono::nanoseconds::max(); - train_.minimal_max_retention_time_ = std::chrono::nanoseconds::max(); + // departs. Schedule departure of current train and create a new one. + schedule_train(); + + train_ = std::make_shared(); + train_->departure_ = its_now + its_retention; } // STEP 9: insert current message buffer - train_.buffer_->insert(train_.buffer_->end(), _data, _data + _size); - train_.passengers_.insert(its_identifier); + train_->buffer_->insert(train_->buffer_->end(), _data, _data + _size); + train_->passengers_.insert(its_identifier); // STEP 9.1: update the trains minimal debounce time if necessary - if (its_debouncing < train_.minimal_debounce_time_) { - train_.minimal_debounce_time_ = its_debouncing; + if (its_debouncing < train_->minimal_debounce_time_) { + train_->minimal_debounce_time_ = its_debouncing; } // STEP 9.2: update the trains minimal maximum retention time if necessary - if (its_retention < train_.minimal_max_retention_time_) { - train_.minimal_max_retention_time_ = its_retention; + if (its_retention < train_->minimal_max_retention_time_) { + train_->minimal_max_retention_time_ = its_retention; } - // STEP 10: restart timer with current departure time -#ifndef _WIN32 - train_.departure_timer_->expires_from_now(train_.departure_); -#else - train_.departure_timer_->expires_from_now( - std::chrono::duration_cast< - std::chrono::steady_clock::duration>(train_.departure_)); -#endif - train_.departure_timer_->async_wait( - std::bind(&client_endpoint_impl::flush_cbk, - this->shared_from_this(), std::placeholders::_1)); + // STEP 10: restart dispatch timer with next departure time + start_dispatch_timer(its_now); return true; } template void client_endpoint_impl::send_segments( - const tp::tp_split_messages_t &_segments) { + const tp::tp_split_messages_t &_segments, std::uint32_t _separation_time) { + + auto its_now(std::chrono::steady_clock::now()); + if (_segments.size() == 0) { return; } - const bool queue_size_zero_on_entry(queue_.empty()); const service_t its_service = VSOMEIP_BYTES_TO_WORD( (*(_segments[0]))[VSOMEIP_SERVICE_POS_MIN], @@ -303,53 +309,49 @@ void client_endpoint_impl::send_segments( get_configured_times_from_endpoint(its_service, its_method, &its_debouncing, &its_retention); // update the trains minimal debounce time if necessary - if (its_debouncing < train_.minimal_debounce_time_) { - train_.minimal_debounce_time_ = its_debouncing; + if (its_debouncing < train_->minimal_debounce_time_) { + train_->minimal_debounce_time_ = its_debouncing; } // update the trains minimal maximum retention time if necessary - if (its_retention < train_.minimal_max_retention_time_) { - train_.minimal_max_retention_time_ = its_retention; + if (its_retention < train_->minimal_max_retention_time_) { + train_->minimal_max_retention_time_ = its_retention; } // We only need to respect the debouncing. There is no need to wait for further // messages as we will send several now anyway. - if (!train_.passengers_.empty()) { - wait_until_debounce_time_reached(); - train_.passengers_.clear(); - queue_train(queue_size_zero_on_entry); - train_.last_departure_ = std::chrono::steady_clock::now(); - train_.departure_ = its_retention; - train_.minimal_debounce_time_ = std::chrono::nanoseconds::max(); - train_.minimal_max_retention_time_ = std::chrono::nanoseconds::max(); + if (!train_->passengers_.empty()) { + schedule_train(); + train_->departure_ = its_now + its_retention; } + const bool queue_size_still_zero(queue_.empty()); for (const auto& s : _segments) { - queue_.emplace_back(s); + queue_.emplace_back(std::make_pair(s, _separation_time)); queue_size_ += s->size(); } if (queue_size_still_zero && !queue_.empty()) { // no writing in progress // respect minimal debounce time - wait_until_debounce_time_reached(); + schedule_train(); // ignore retention time and send immediately as the train is full anyway - auto its_buffer = get_front(); - if (its_buffer) { + auto its_entry = get_front(); + if (its_entry.first) { strand_.dispatch(std::bind(&client_endpoint_impl::send_queued, - this->shared_from_this(), its_buffer)); + this->shared_from_this(), its_entry)); } } - train_.last_departure_ = std::chrono::steady_clock::now(); } template -void client_endpoint_impl::wait_until_debounce_time_reached() const { - const std::chrono::nanoseconds time_since_last_departure = - std::chrono::duration_cast( - std::chrono::steady_clock::now() - train_.last_departure_); - if (time_since_last_departure < train_.minimal_debounce_time_) { - std::this_thread::sleep_for( - train_.minimal_debounce_time_ - time_since_last_departure); +void client_endpoint_impl::schedule_train() { + + if (has_last_departure_) { + if (last_departure_ + train_->minimal_debounce_time_ > train_->departure_) { + train_->departure_ = last_departure_ + train_->minimal_debounce_time_; + } } + + dispatched_trains_[train_->departure_].push_back(train_); } template @@ -363,24 +365,58 @@ bool client_endpoint_impl::send(const std::vector& _cmd_header template bool client_endpoint_impl::flush() { - bool is_successful(true); + + bool has_queued(true); + bool is_current_train(true); + std::lock_guard its_lock(mutex_); - if (!train_.buffer_->empty()) { - queue_train(!queue_.size()); - train_.last_departure_ = std::chrono::steady_clock::now(); - train_.passengers_.clear(); - train_.minimal_debounce_time_ = std::chrono::nanoseconds::max(); - train_.minimal_max_retention_time_ = std::chrono::nanoseconds::max(); + + std::shared_ptr its_train(train_); + if (!dispatched_trains_.empty()) { + + auto its_dispatched = dispatched_trains_.begin(); + if (its_dispatched->first <= its_train->departure_) { + + is_current_train = false; + its_train = its_dispatched->second.front(); + its_dispatched->second.pop_front(); + if (its_dispatched->second.empty()) { + + dispatched_trains_.erase(its_dispatched); + } + } + } + + if (!its_train->buffer_->empty()) { + + queue_train(its_train, !queue_.size()); + + // Reset current train if necessary + if (is_current_train) { + its_train->reset(); + } } else { - is_successful = false; + has_queued = false; } - return is_successful; + if (!is_current_train || !dispatched_trains_.empty()) { + + auto its_now(std::chrono::steady_clock::now()); + start_dispatch_timer(its_now); + } + + return (has_queued); } template void client_endpoint_impl::connect_cbk( boost::system::error_code const &_error) { + + if (_error != boost::asio::error::timed_out) { + std::lock_guard its_lock(connecting_timer_mutex_); + connecting_timer_.cancel(); + } + if (_error == boost::asio::error::operation_aborted || endpoint_impl::sending_blocked_) { // endpoint was stopped @@ -416,10 +452,10 @@ void client_endpoint_impl::connect_cbk( if (was_not_connected_) { was_not_connected_ = false; std::lock_guard its_lock(mutex_); - auto its_buffer = get_front(); - if (its_buffer) { + auto its_entry = get_front(); + if (its_entry.first) { strand_.dispatch(std::bind(&client_endpoint_impl::send_queued, - this->shared_from_this(), its_buffer)); + this->shared_from_this(), its_entry)); VSOMEIP_WARNING << __func__ << ": resume sending to: " << get_remote_information(); } @@ -435,6 +471,7 @@ void client_endpoint_impl::connect_cbk( template void client_endpoint_impl::wait_connect_cbk( boost::system::error_code const &_error) { + if (!_error && !client_endpoint_impl::sending_blocked_) { auto self = this->shared_from_this(); strand_.dispatch(std::bind(&client_endpoint_impl::connect, @@ -442,19 +479,33 @@ void client_endpoint_impl::wait_connect_cbk( } } +template +void client_endpoint_impl::wait_connecting_cbk( + boost::system::error_code const &_error) { + if (!_error && !client_endpoint_impl::sending_blocked_) { + connect_cbk(boost::asio::error::timed_out); + } +} + template void client_endpoint_impl::send_cbk( boost::system::error_code const &_error, std::size_t _bytes, const message_buffer_ptr_t& _sent_msg) { + (void)_bytes; + if (!_error) { std::lock_guard its_lock(mutex_); if (queue_.size() > 0) { - queue_size_ -= queue_.front()->size(); + queue_size_ -= queue_.front().first->size(); queue_.pop_front(); - auto its_buffer = get_front(); - if (its_buffer) - send_queued(its_buffer); + + update_last_departure(); + + auto its_entry = get_front(); + if (its_entry.first) { + send_queued(its_entry); + } } } else if (_error == boost::asio::error::broken_pipe) { state_ = cei_state_e::CLOSED; @@ -563,6 +614,7 @@ void client_endpoint_impl::send_cbk( template void client_endpoint_impl::flush_cbk( boost::system::error_code const &_error) { + if (!_error) { (void) flush(); } @@ -570,15 +622,17 @@ void client_endpoint_impl::flush_cbk( template void client_endpoint_impl::shutdown_and_close_socket(bool _recreate_socket) { + std::lock_guard its_lock(socket_mutex_); shutdown_and_close_socket_unlocked(_recreate_socket); } template void client_endpoint_impl::shutdown_and_close_socket_unlocked(bool _recreate_socket) { + local_port_ = 0; if (socket_->is_open()) { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) if (-1 == fcntl(socket_->native_handle(), F_GETFD)) { VSOMEIP_ERROR << "cei::shutdown_and_close_socket_unlocked: socket/handle closed already '" << std::string(std::strerror(errno)) @@ -590,34 +644,39 @@ void client_endpoint_impl::shutdown_and_close_socket_unlocked(bool _re socket_->close(its_error); } if (_recreate_socket) { - socket_.reset(new socket_type(endpoint_impl::service_)); + socket_.reset(new socket_type(endpoint_impl::io_)); } } template bool client_endpoint_impl::get_remote_address( boost::asio::ip::address &_address) const { + (void)_address; return false; } template std::uint16_t client_endpoint_impl::get_remote_port() const { + return 0; } template std::uint16_t client_endpoint_impl::get_local_port() const { + return local_port_; } template void client_endpoint_impl::set_local_port(uint16_t _port) { + local_port_ = _port; } template void client_endpoint_impl::start_connect_timer() { + std::lock_guard its_lock(connect_timer_mutex_); connect_timer_.expires_from_now( std::chrono::milliseconds(connect_timeout_)); @@ -626,9 +685,21 @@ void client_endpoint_impl::start_connect_timer() { this->shared_from_this(), std::placeholders::_1)); } +template +void client_endpoint_impl::start_connecting_timer() { + + std::lock_guard its_lock(connecting_timer_mutex_); + connecting_timer_.expires_from_now( + std::chrono::milliseconds(connecting_timeout_)); + connecting_timer_.async_wait( + std::bind(&client_endpoint_impl::wait_connecting_cbk, + this->shared_from_this(), std::placeholders::_1)); +} + template typename endpoint_impl::cms_ret_e client_endpoint_impl::check_message_size( const std::uint8_t * const _data, std::uint32_t _size) { + typename endpoint_impl::cms_ret_e ret(endpoint_impl::cms_ret_e::MSG_OK); if (endpoint_impl::max_message_size_ != MESSAGE_SIZE_UNLIMITED && _size > endpoint_impl::max_message_size_) { @@ -640,11 +711,20 @@ typename endpoint_impl::cms_ret_e client_endpoint_impl::chec _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); if (tp_segmentation_enabled(its_service, its_method)) { - send_segments(tp::tp::tp_split_message(_data, _size)); - return endpoint_impl::cms_ret_e::MSG_WAS_SPLIT; + instance_t its_instance = this->get_instance(its_service); + if (its_instance != 0xFFFF) { + std::uint16_t its_max_segment_length; + std::uint32_t its_separation_time; + this->configuration_->get_tp_configuration( + its_service, its_instance, its_method, true, + its_max_segment_length, its_separation_time); + send_segments(tp::tp::tp_split_message(_data, _size, + its_max_segment_length), its_separation_time); + return endpoint_impl::cms_ret_e::MSG_WAS_SPLIT; + } } } - VSOMEIP_ERROR << "cei::check_message_size: Dropping too big message (" + VSOMEIP_ERROR << "cei::check_message_size: Dropping to big message (" << std::dec << _size << " Bytes). Maximum allowed message size is: " << endpoint_impl::max_message_size_ << " Bytes."; ret = endpoint_impl::cms_ret_e::MSG_TOO_BIG; @@ -654,6 +734,7 @@ typename endpoint_impl::cms_ret_e client_endpoint_impl::chec template bool client_endpoint_impl::check_queue_limit(const uint8_t *_data, std::uint32_t _size) const { + if (endpoint_impl::queue_limit_ != QUEUE_SIZE_UNLIMITED && queue_size_ + _size > endpoint_impl::queue_limit_) { service_t its_service(0); @@ -692,31 +773,84 @@ bool client_endpoint_impl::check_queue_limit(const uint8_t *_data, std } template -void client_endpoint_impl::queue_train(bool _queue_size_zero_on_entry) { - queue_.push_back(train_.buffer_); - queue_size_ += train_.buffer_->size(); - train_.buffer_ = std::make_shared(); +void client_endpoint_impl::queue_train( + const std::shared_ptr &_train, bool _queue_size_zero_on_entry) { + + queue_.push_back(std::make_pair(_train->buffer_, 0)); + queue_size_ += _train->buffer_->size(); + if (_queue_size_zero_on_entry && !queue_.empty()) { // no writing in progress - auto its_buffer = get_front(); - if (its_buffer) { + auto its_entry = get_front(); + if (its_entry.first) { strand_.dispatch(std::bind(&client_endpoint_impl::send_queued, - this->shared_from_this(), its_buffer)); + this->shared_from_this(), its_entry)); } } } template size_t client_endpoint_impl::get_queue_size() const { + std::lock_guard its_lock(mutex_); return queue_size_; } +template +void client_endpoint_impl::start_dispatch_timer( + const std::chrono::steady_clock::time_point &_now) { + + // Choose the next train + std::shared_ptr its_train(train_); + if (!dispatched_trains_.empty()) { + + auto its_dispatched = dispatched_trains_.begin(); + if (its_dispatched->first < its_train->departure_) { + + its_train = its_dispatched->second.front(); + } + } + + std::chrono::nanoseconds its_offset; + if (its_train->departure_ > _now) { + + its_offset = std::chrono::duration_cast( + its_train->departure_ - _now); + } else { // already departure time + + its_offset = std::chrono::nanoseconds::zero(); + } + +#if defined(__linux__) || defined(ANDROID) + dispatch_timer_.expires_from_now(its_offset); +#else + dispatch_timer_.expires_from_now( + std::chrono::duration_cast< + std::chrono::steady_clock::duration>(its_offset)); +#endif + dispatch_timer_.async_wait( + std::bind(&client_endpoint_impl::flush_cbk, + this->shared_from_this(), std::placeholders::_1)); +} + +template +void client_endpoint_impl::cancel_dispatch_timer() { + + boost::system::error_code ec; + dispatch_timer_.cancel(ec); +} + +template +void client_endpoint_impl::update_last_departure() { + + last_departure_ = std::chrono::steady_clock::now(); + has_last_departure_ = true; +} + // Instantiate template -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) template class client_endpoint_impl; #endif template class client_endpoint_impl; template class client_endpoint_impl; } // namespace vsomeip_v3 - diff --git a/implementation/endpoints/src/credentials.cpp b/implementation/endpoints/src/credentials.cpp index 3b9762c..70d8dcc 100644 --- a/implementation/endpoints/src/credentials.cpp +++ b/implementation/endpoints/src/credentials.cpp @@ -1,10 +1,12 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) +#include +#include #include #include "../include/credentials.hpp" @@ -21,7 +23,7 @@ namespace vsomeip_v3 { void credentials::activate_credentials(const int _fd) { int optval = 1; if (setsockopt(_fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) == -1) { - VSOMEIP_ERROR << "vSomeIP Security: Activating socket option for receiving " + VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Activating socket option for receiving " << "credentials failed."; } } @@ -29,70 +31,94 @@ void credentials::activate_credentials(const int _fd) { void credentials::deactivate_credentials(const int _fd) { int optval = 0; if (setsockopt(_fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) == -1) { - VSOMEIP_ERROR << "vSomeIP Security: Deactivating socket option for receiving " + VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Deactivating socket option for receiving " << "credentials failed."; } } -client_t credentials::receive_credentials(const int _fd, uid_t& _uid, gid_t& _gid) { - struct ucred *ucredp; +boost::optional credentials::receive_credentials(const int _fd) { struct msghdr msgh; - struct iovec iov; + struct iovec iov[2]; union { struct cmsghdr cmh; char control[CMSG_SPACE(sizeof(struct ucred))]; } control_un; - struct cmsghdr *cmhp; - // Sender client_id will be received as data - client_t client = VSOMEIP_ROUTING_CLIENT; - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; + // We don't need address of peer as we using connect + msgh.msg_name = NULL; + msgh.msg_namelen = 0; + + // Set fields of 'msgh' to point to buffer used to receive (real) data read by recvmsg() + msgh.msg_iov = iov; + msgh.msg_iovlen = 2; // Set 'msgh' fields to describe 'control_un' msgh.msg_control = control_un.control; msgh.msg_controllen = sizeof(control_un.control); - // Set fields of 'msgh' to point to buffer used to receive (real) data read by recvmsg() - msgh.msg_iov = &iov; - msgh.msg_iovlen = 1; - iov.iov_base = &client; - iov.iov_len = sizeof(client_t); + // Sender client_id and client_host_length will be received as data + client_t client = VSOMEIP_ROUTING_CLIENT; + uint8_t client_host_length(0); + iov[0].iov_base = &client; + iov[0].iov_len = sizeof(client_t); + iov[1].iov_base = &client_host_length; + iov[1].iov_len = sizeof(uint8_t); - // We don't need address of peer as we using connect - msgh.msg_name = NULL; - msgh.msg_namelen = 0; + // Set 'control_un' to describe ancillary data that we want to receive + control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); + control_un.cmh.cmsg_level = SOL_SOCKET; + control_un.cmh.cmsg_type = SCM_CREDENTIALS; - // Receive client_id plus ancillary data + // Receive client_id plus client_host_length plus ancillary data ssize_t nr = recvmsg(_fd, &msgh, 0); if (nr == -1) { - VSOMEIP_ERROR << "vSomeIP Security: Receiving credentials failed. No data."; + VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Receiving credentials failed. No data. errno: " << std::strerror(errno); + return boost::none; } - cmhp = CMSG_FIRSTHDR(&msgh); + struct cmsghdr* cmhp = CMSG_FIRSTHDR(&msgh); if (cmhp == NULL || cmhp->cmsg_len != CMSG_LEN(sizeof(struct ucred)) || cmhp->cmsg_level != SOL_SOCKET || cmhp->cmsg_type != SCM_CREDENTIALS) { - VSOMEIP_ERROR << "vSomeIP Security: Receiving credentials failed. Invalid data."; - } else { - ucredp = (struct ucred *) CMSG_DATA(cmhp); - _uid = ucredp->uid; - _gid = ucredp->gid; + VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Receiving credentials failed. Invalid data."; + return boost::none; } - return client; + // Use the implicitly-defined copy constructor + struct ucred ucred = *reinterpret_cast(CMSG_DATA(cmhp)); + + msgh.msg_iov = iov; + msgh.msg_iovlen = 1; + msgh.msg_control = nullptr; + msgh.msg_controllen = 0; + + // Receive client_host as data + std::string client_host(client_host_length, '\0'); + iov[0].iov_base = &client_host.front(); + iov[0].iov_len = client_host.length(); + + nr = recvmsg(_fd, &msgh, 0); + if (nr == -1) { + VSOMEIP_ERROR << __func__ << ": vSomeIP Security: Receiving client host failed. No data. errno: " << std::strerror(errno); + return boost::none; + } + + return received_t{client, ucred.uid, ucred.gid, client_host}; } -void credentials::send_credentials(const int _fd, client_t _client) { +void credentials::send_credentials(const int _fd, client_t _client, std::string _client_host) { struct msghdr msgh; - struct iovec iov; + struct iovec iov[3]; + uint8_t client_host_length = (uint8_t)_client_host.length(); // data to send - msgh.msg_iov = &iov; - msgh.msg_iovlen = 1; - iov.iov_base = &_client; - iov.iov_len = sizeof(client_t); + msgh.msg_iov = &iov[0]; + msgh.msg_iovlen = 3; + iov[0].iov_base = &_client; + iov[0].iov_len = sizeof(client_t); + iov[1].iov_base = &client_host_length; + iov[1].iov_len = sizeof(uint8_t); + iov[2].iov_base = &_client_host[0]; + iov[2].iov_len = client_host_length; // destination not needed as we use connect msgh.msg_name = NULL; @@ -105,11 +131,10 @@ void credentials::send_credentials(const int _fd, client_t _client) { // send client id with credentials ssize_t ns = sendmsg(_fd, &msgh, 0); if (ns == -1) { - VSOMEIP_ERROR << "Sending credentials failed."; + VSOMEIP_ERROR << __func__ << ": Sending credentials failed. errno: " << std::strerror(errno); } } } // namespace vsomeip_v3 -#endif // #ifndef _WIN32 - +#endif // __linux__ || ANDROID diff --git a/implementation/endpoints/src/endpoint_definition.cpp b/implementation/endpoints/src/endpoint_definition.cpp index 9547836..ff6ff7b 100644 --- a/implementation/endpoints/src/endpoint_definition.cpp +++ b/implementation/endpoints/src/endpoint_definition.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/endpoints/src/endpoint_impl.cpp b/implementation/endpoints/src/endpoint_impl.cpp index 4bb2fc0..9835315 100644 --- a/implementation/endpoints/src/endpoint_impl.cpp +++ b/implementation/endpoints/src/endpoint_impl.cpp @@ -1,13 +1,15 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include #include -#include #include +#if VSOMEIP_BOOST_VERSION < 106600 #include +#include +#endif #include #include @@ -24,11 +26,11 @@ endpoint_impl::endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, - boost::asio::io_service &_io, + boost::asio::io_context &_io, std::uint32_t _max_message_size, configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration) - : service_(_io), + : io_(_io), endpoint_host_(_endpoint_host), routing_host_(_routing_host), is_supporting_magic_cookies_(false), @@ -125,18 +127,32 @@ uint32_t endpoint_impl::get_use_count() { } template -void endpoint_impl::register_error_handler(error_handler_t _error_handler) { +void endpoint_impl::register_error_handler(const error_handler_t &_error_handler) { std::lock_guard its_lock(error_handler_mutex_); this->error_handler_ = _error_handler; } +template +instance_t endpoint_impl::get_instance(service_t _service) { + + instance_t its_instance(0xFFFF); + + auto its_host = endpoint_host_.lock(); + if (its_host) + its_instance = its_host->find_instance(_service, this); + + return (its_instance); +} + // Instantiate template -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) template class endpoint_impl; +#if VSOMEIP_BOOST_VERSION < 106600 template class endpoint_impl; +template class endpoint_impl; +#endif #endif template class endpoint_impl; template class endpoint_impl; -template class endpoint_impl; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/endpoint_manager_base.cpp b/implementation/endpoints/src/endpoint_manager_base.cpp index cfddc87..b8e18af 100644 --- a/implementation/endpoints/src/endpoint_manager_base.cpp +++ b/implementation/endpoints/src/endpoint_manager_base.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -9,20 +9,28 @@ #include "../../utility/include/utility.hpp" #include "../../routing/include/routing_manager_base.hpp" #include "../../configuration/include/configuration.hpp" -#include "../include/local_client_endpoint_impl.hpp" -#include "../include/local_server_endpoint_impl.hpp" +#include "../include/local_tcp_client_endpoint_impl.hpp" +#include "../include/local_tcp_server_endpoint_impl.hpp" + +#if defined(__linux__) || defined(ANDROID) +#include "../include/local_uds_client_endpoint_impl.hpp" +#include "../include/local_uds_server_endpoint_impl.hpp" +#endif #include namespace vsomeip_v3 { -endpoint_manager_base::endpoint_manager_base(routing_manager_base* const _rm, - boost::asio::io_service& _io, - const std::shared_ptr& _configuration) : - rm_(_rm), - io_(_io), - configuration_(_configuration){ +endpoint_manager_base::endpoint_manager_base( + routing_manager_base* const _rm, + boost::asio::io_context &_io, + const std::shared_ptr& _configuration) + : rm_(_rm), + io_(_io), + configuration_(_configuration), + local_port_(ILLEGAL_PORT) { + is_local_routing_ = configuration_->is_local_routing(); } std::shared_ptr endpoint_manager_base::create_local(client_t _client) { @@ -72,47 +80,81 @@ std::unordered_set endpoint_manager_base::get_connected_clients() cons return clients; } -std::shared_ptr endpoint_manager_base::create_local_server( - const std::shared_ptr& _routing_host) { - std::shared_ptr its_server_endpoint; +std::shared_ptr endpoint_manager_base::create_local_server( + const std::shared_ptr &_routing_host) { + std::shared_ptr its_server_endpoint; std::stringstream its_path; - its_path << utility::get_base_path(configuration_) << std::hex << rm_->get_client(); + its_path << utility::get_base_path(configuration_->get_network()) + << std::hex << rm_->get_client(); const client_t its_client = rm_->get_client(); -#ifdef _WIN32 - ::_unlink(its_path.str().c_str()); - int port = VSOMEIP_INTERNAL_BASE_PORT + its_client; -#else - if (-1 == ::unlink(its_path.str().c_str()) && errno != ENOENT) { - VSOMEIP_ERROR << "endpoint_manager_base::init_receiver unlink failed (" - << its_path.str() << "): "<< std::strerror(errno); - } -#endif - try { - its_server_endpoint = std::make_shared( - shared_from_this(), _routing_host, -#ifdef _WIN32 - boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port), -#else - boost::asio::local::stream_protocol_ext::endpoint(its_path.str()), -#endif - io_, - configuration_, false); -#ifdef _WIN32 - VSOMEIP_INFO << "Listening at " << port; -#else - VSOMEIP_INFO << "Listening at " << its_path.str(); -#endif - } catch (const std::exception &e) { - VSOMEIP_ERROR << "Local server endpoint creation failed. Client ID: " - << std::hex << std::setw(4) << std::setfill('0') << its_client -#ifdef _WIN32 - << " Port: " << std::dec << port + +#if defined(__linux__) || defined(ANDROID) + if (is_local_routing_) { + if (-1 == ::unlink(its_path.str().c_str()) && errno != ENOENT) { + VSOMEIP_ERROR << "endpoint_manager_base::init_receiver unlink failed (" + << its_path.str() << "): "<< std::strerror(errno); + } + try { + its_server_endpoint = std::make_shared( + shared_from_this(), _routing_host, +# if VSOMEIP_BOOST_VERSION < 106600 + boost::asio::local::stream_protocol_ext::endpoint(its_path.str()), +# else + boost::asio::local::stream_protocol::endpoint(its_path.str()), +# endif + io_, + configuration_, false); + + VSOMEIP_INFO << __func__ << ": Listening @ " << its_path.str(); + + } catch (const std::exception &e) { + VSOMEIP_ERROR << "Local UDS server endpoint creation failed. Client " + << std::hex << std::setw(4) << std::setfill('0') << its_client + << " Path: " << its_path.str() + << " Reason: " << e.what(); + } + } else { #else - << " Path: " << its_path.str() + { #endif - << " Reason: " << e.what(); + std::lock_guard its_lock(create_local_server_endpoint_mutex_); + ::unlink(its_path.str().c_str()); + port_t its_port; + std::set its_used_ports; + auto its_address = configuration_->get_routing_guest_address(); + while (get_local_server_port(its_port, its_used_ports) && !its_server_endpoint) { + try { + its_server_endpoint = std::make_shared( + shared_from_this(), _routing_host, + boost::asio::ip::tcp::endpoint(its_address, its_port), + io_, + configuration_, false); + + VSOMEIP_INFO << __func__ << ": Listening @ " + << its_address.to_string() << ":" << std::dec << its_port; + + if (rm_->is_routing_manager()) + local_port_ = port_t(configuration_->get_routing_host_port() + 1); + else + local_port_ = port_t(its_port + 1); + VSOMEIP_INFO << __func__ << ": Connecting to other clients from " + << its_address.to_string() << ":" << std::dec << local_port_; + + } catch (const std::exception&) { + its_used_ports.insert(its_port); + } + } + + if (!its_server_endpoint) { + VSOMEIP_ERROR << "Local TCP server endpoint creation failed. Client " + << std::hex << std::setw(4) << std::setfill('0') << its_client + << " Reason: No local port available!"; + } else { + rm_->add_guest(its_client, its_address, its_port); + } } - return its_server_endpoint; + + return (its_server_endpoint); } void endpoint_manager_base::on_connect(std::shared_ptr _endpoint) { @@ -123,23 +165,27 @@ void endpoint_manager_base::on_disconnect(std::shared_ptr _endpoint) { rm_->on_disconnect(_endpoint); } -bool endpoint_manager_base::on_bind_error(std::shared_ptr _endpoint, uint16_t _remote_port) { +bool endpoint_manager_base::on_bind_error(std::shared_ptr _endpoint, + const boost::asio::ip::address &_remote_address, + uint16_t _remote_port) { + (void)_endpoint; + (void)_remote_address; (void)_remote_port; + return true; - // intentionally left blank } void endpoint_manager_base::on_error( const byte_t *_data, length_t _length, endpoint* const _receiver, const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port) { + (void)_data; (void)_length; (void)_receiver; (void)_remote_address; (void)_remote_port; - // intentionally left blank } void endpoint_manager_base::release_port(uint16_t _port, bool _reliable) { @@ -152,6 +198,10 @@ client_t endpoint_manager_base::get_client() const { return rm_->get_client(); } +std::string endpoint_manager_base::get_client_host() const { + return rm_->get_client_host(); +} + std::map> endpoint_manager_base::get_local_endpoints() const { std::lock_guard its_lock(local_endpoint_mutex_); @@ -193,39 +243,69 @@ endpoint_manager_base::log_client_states() const { VSOMEIP_WARNING << "ICQ: [" << its_log.str() << "]"; } -std::shared_ptr endpoint_manager_base::create_local_unlocked(client_t _client) { +std::shared_ptr +endpoint_manager_base::create_local_unlocked(client_t _client) { + std::stringstream its_path; - its_path << utility::get_base_path(configuration_) << std::hex << _client; - std::shared_ptr its_endpoint; - -#ifdef _WIN32 - boost::asio::ip::address address = boost::asio::ip::address::from_string("127.0.0.1"); - int port = VSOMEIP_INTERNAL_BASE_PORT + _client; - VSOMEIP_INFO << "Connecting to [" - << std::hex << _client << "] at " << port; -#else - VSOMEIP_INFO << "Client [" << std::hex << rm_->get_client() << "] is connecting to [" + its_path << utility::get_base_path(configuration_->get_network()) + << std::hex << _client; + std::shared_ptr its_endpoint; + +#if defined(__linux__) || defined(ANDROID) + if (is_local_routing_) { + VSOMEIP_INFO << "Client [" << std::hex << rm_->get_client() << "] is connecting to [" << std::hex << _client << "] at " << its_path.str(); -#endif - its_endpoint = std::make_shared( + its_endpoint = std::make_shared( shared_from_this(), rm_->shared_from_this(), -#ifdef _WIN32 - boost::asio::ip::tcp::endpoint(address, port) + boost::asio::local::stream_protocol::endpoint(its_path.str()), + io_, configuration_); + } else { #else - boost::asio::local::stream_protocol::endpoint(its_path.str()) + { #endif - , io_, configuration_); - - // Messages sent to the VSOMEIP_ROUTING_CLIENT are meant to be routed to - // external devices. Therefore, its local endpoint must not be found by - // a call to find_local. Thus it must not be inserted to the list of local - // clients. - if (_client != VSOMEIP_ROUTING_CLIENT) { - local_endpoints_[_client] = its_endpoint; + boost::asio::ip::address its_local_address, its_remote_address; + port_t its_remote_port; + + bool is_guest = rm_->get_guest(_client, its_remote_address, its_remote_port); + if (is_guest) { + try { + its_local_address = configuration_->get_routing_guest_address(); + its_endpoint = std::make_shared( + shared_from_this(), rm_->shared_from_this(), + boost::asio::ip::tcp::endpoint(its_local_address, local_port_), + boost::asio::ip::tcp::endpoint(its_remote_address, its_remote_port), + io_, configuration_); + + VSOMEIP_INFO << "Client [" + << std::hex << std::setw(4) << std::setfill('0') << rm_->get_client() + << "] @ " + << its_local_address.to_string() << ":" << std::dec << local_port_ + << " is connecting to [" + << std::hex << std::setw(4) << std::setfill('0') << _client << "] @ " + << its_remote_address.to_string() << ":" << std::dec << its_remote_port; + + } catch (...) { + } + } else { + VSOMEIP_ERROR << __func__ + << ": Cannot get guest address of client [" + << std::hex << std::setw(4) << std::setfill('0') + << _client << "]"; + } } - rm_->register_client_error_handler(_client, its_endpoint); - return its_endpoint; + if (its_endpoint) { + // Messages sent to the VSOMEIP_ROUTING_CLIENT are meant to be routed to + // external devices. Therefore, its local endpoint must not be found by + // a call to find_local. Thus it must not be inserted to the list of local + // clients. + if (_client != VSOMEIP_ROUTING_CLIENT) { + local_endpoints_[_client] = its_endpoint; + } + rm_->register_client_error_handler(_client, its_endpoint); + } + + return (its_endpoint); } std::shared_ptr endpoint_manager_base::find_local_unlocked(client_t _client) { @@ -237,4 +317,43 @@ std::shared_ptr endpoint_manager_base::find_local_unlocked(client_t _c return (its_endpoint); } +instance_t endpoint_manager_base::find_instance( + service_t _service, endpoint* const _endpoint) const { + + (void)_service; + (void)_endpoint; + + return (0xFFFF); +} + +bool +endpoint_manager_base::get_local_server_port(port_t &_port, + const std::set &_used_ports) const { + +#define SERVER_PORT_OFFSET 2 + + auto its_port_ranges = configuration_->get_routing_guest_ports(); + + for (const auto &its_range : its_port_ranges) { + for (int r = its_range.first; r < its_range.second; + r += SERVER_PORT_OFFSET) { + + if (_used_ports.find(port_t(r)) == _used_ports.end() + && r != configuration_->get_routing_host_port()) { + + _port = port_t(r); + return (true); + } + } + } + + return (false); +} + +void +endpoint_manager_base::add_multicast_option(const multicast_option_t &_option) { + + (void)_option; +} + } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/endpoint_manager_impl.cpp b/implementation/endpoints/src/endpoint_manager_impl.cpp index dbb2107..a47234c 100644 --- a/implementation/endpoints/src/endpoint_manager_impl.cpp +++ b/implementation/endpoints/src/endpoint_manager_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -7,17 +7,19 @@ #include +#include "../include/local_tcp_server_endpoint_impl.hpp" +#if defined(__linux__) || defined(ANDROID) +#include "../include/local_uds_server_endpoint_impl.hpp" +#endif #include "../include/udp_client_endpoint_impl.hpp" #include "../include/udp_server_endpoint_impl.hpp" #include "../include/tcp_client_endpoint_impl.hpp" #include "../include/tcp_server_endpoint_impl.hpp" -#include "../include/local_server_endpoint_impl.hpp" #include "../include/virtual_server_endpoint_impl.hpp" #include "../include/endpoint_definition.hpp" #include "../../routing/include/routing_manager_base.hpp" #include "../../routing/include/routing_manager_impl.hpp" #include "../../routing/include/routing_host.hpp" -#include "../../security/include/security.hpp" #include "../../utility/include/utility.hpp" #include "../../utility/include/byteorder.hpp" @@ -33,9 +35,28 @@ namespace vsomeip_v3 { endpoint_manager_impl::endpoint_manager_impl( - routing_manager_base* const _rm, boost::asio::io_service& _io, + routing_manager_base* const _rm, boost::asio::io_context &_io, const std::shared_ptr& _configuration) : - endpoint_manager_base(_rm, _io, _configuration) { + endpoint_manager_base(_rm, _io, _configuration), + is_processing_options_(true), + options_thread_(std::bind(&endpoint_manager_impl::process_multicast_options, this)) { + + local_port_ = port_t(_configuration->get_routing_host_port() + 1); + if (!is_local_routing_) { + VSOMEIP_INFO << __func__ << ": Connecting to other clients from " + << configuration_->get_routing_host_address().to_string() + << ":" << std::dec << local_port_; + } +} + +endpoint_manager_impl::~endpoint_manager_impl() { + + { + std::lock_guard its_guard(options_mutex_); + is_processing_options_ = false; + options_condition_.notify_one(); + } + options_thread_.join(); } std::shared_ptr endpoint_manager_impl::find_or_create_remote_client( @@ -266,9 +287,7 @@ std::shared_ptr endpoint_manager_impl::create_server_endpoint( << " Server endpoint creation failed." << " Reason: "<< e.what() << " Port: " << _port - << " (reliable=" - << (_reliable ? "reliable" : "unreliable") - << ")"; + << " (" << _reliable << ")"; } return (its_endpoint); @@ -457,6 +476,7 @@ void endpoint_manager_impl::find_or_create_multicast_endpoint( // Only save multicast info if we created a new endpoint // to be able to delete the new endpoint // as soon as the instance stops offering its service + std::lock_guard its_lock(endpoint_mutex_); std::shared_ptr endpoint_def = endpoint_definition::get(_address, _port, false, _service, _instance); multicast_info[_service][_instance] = endpoint_def; @@ -588,79 +608,139 @@ void endpoint_manager_impl::print_status() const { } } -std::shared_ptr -endpoint_manager_impl::create_local_server( - bool* _is_socket_activated, - const std::shared_ptr& _routing_host) { - std::shared_ptr its_endpoint; +bool +endpoint_manager_impl::create_routing_root( + std::shared_ptr &_root, + bool &_is_socket_activated, + const std::shared_ptr &_host) { + std::stringstream its_endpoint_path_ss; - its_endpoint_path_ss << utility::get_base_path(configuration_) << VSOMEIP_ROUTING_CLIENT; + its_endpoint_path_ss << utility::get_base_path(configuration_->get_network()) + << VSOMEIP_ROUTING_CLIENT; const std::string its_endpoint_path = its_endpoint_path_ss.str(); - client_t routing_host_id = configuration_->get_id(configuration_->get_routing_host()); - if (security::get()->is_enabled() && get_client() != routing_host_id) { - VSOMEIP_ERROR << "endpoint_manager_impl::create_local_server: " - << std::hex << "Client " << get_client() << " isn't allowed" - << " to create the routing endpoint as its not configured as the routing master!"; - return its_endpoint; + client_t its_routing_host_id = configuration_->get_id(configuration_->get_routing_host_name()); + if (configuration_->is_security_enabled() && get_client() != its_routing_host_id) { + VSOMEIP_ERROR << "endpoint_manager_impl::" << __func__ << ": " + << "Client [" + << std::hex << std::setw(4) << std::setfill('0') + << get_client() + << "] does not match the configured routing manager client identifier [" + << std::hex << std::setw(4) << std::setfill('0') + << its_routing_host_id + << "]"; + + return (false); } - uint32_t native_socket_fd = 0; - int32_t num_fd = 0; + + if (configuration_->is_local_routing()) { + uint32_t native_socket_fd = 0; + int32_t num_fd = 0; #ifndef WITHOUT_SYSTEMD - num_fd = sd_listen_fds(0); + num_fd = sd_listen_fds(0); +#endif + +#if defined(__linux__) || defined(ANDROID) + if (num_fd > 1) { + VSOMEIP_ERROR << "Too many file descriptors received by systemd socket activation! num_fd: " << num_fd; + } else if (num_fd == 1) { + native_socket_fd = SD_LISTEN_FDS_START + 0; + VSOMEIP_INFO << "Using native socket created by systemd socket activation! fd: " << native_socket_fd; + if (is_local_routing_) { + try { + _root = + std::make_shared ( + shared_from_this(), _host, +#if VSOMEIP_BOOST_VERSION < 106600 + boost::asio::local::stream_protocol_ext::endpoint(its_endpoint_path), +#else + boost::asio::local::stream_protocol::endpoint(its_endpoint_path), #endif - if (num_fd > 1) { - VSOMEIP_ERROR << "Too many file descriptors received by systemd socket activation! num_fd: " << num_fd; - } else if (num_fd == 1) { - native_socket_fd = SD_LISTEN_FDS_START + 0; - VSOMEIP_INFO << "Using native socket created by systemd socket activation! fd: " << native_socket_fd; - #ifndef _WIN32 - try { - its_endpoint = - std::make_shared ( - shared_from_this(), _routing_host, + io_, + native_socket_fd, + configuration_, true); + } catch (const std::exception &e) { + VSOMEIP_ERROR << "Routing endpoint creation failed. Client ID: " + << std::hex << std::setw(4) << std::setfill('0') + << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); + } + } + _is_socket_activated = true; + + } else { + if (is_local_routing_) { + if (-1 == ::unlink(its_endpoint_path.c_str()) && errno != ENOENT) { + VSOMEIP_ERROR << "endpoint_manager_impl::create_local_server unlink failed (" + << its_endpoint_path << "): "<< std::strerror(errno); + } + VSOMEIP_INFO << __func__ << ": Routing root @ " << its_endpoint_path; + + try { + _root = + std::make_shared ( + shared_from_this(), _host, +#if VSOMEIP_BOOST_VERSION < 106600 boost::asio::local::stream_protocol_ext::endpoint(its_endpoint_path), - io_, - native_socket_fd, - configuration_, true); - } catch (const std::exception &e) { - VSOMEIP_ERROR << "Server endpoint creation failed. Client ID: " - << std::hex << std::setw(4) << std::setfill('0') - << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); +#else + boost::asio::local::stream_protocol::endpoint(its_endpoint_path), +#endif + io_, configuration_, true); + } catch (const std::exception &e) { + VSOMEIP_ERROR << "Local routing endpoint creation failed. Client ID: " + << std::hex << std::setw(4) << std::setfill('0') + << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); + + return (false); + } } - #endif - *_is_socket_activated = true; + + _is_socket_activated = false; + } +#else + ::unlink(its_endpoint_path.c_str()); + port_t port = VSOMEIP_INTERNAL_BASE_PORT; + VSOMEIP_INFO << __func__ << ": Routing root @ " << std::dec << port; + + try { + _root = + std::make_shared ( + shared_from_this(), _host, + boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port), + io_, configuration_, true); + } catch (const std::exception &e) { + VSOMEIP_ERROR << "Local routing endpoint creation failed. Client ID: " + << std::hex << std::setw(4) << std::setfill('0') + << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); + + return (false); + } + + _is_socket_activated = false; +#endif // __linux__ || ANDROID } else { - #if _WIN32 - ::_unlink(its_endpoint_path.c_str()); - int port = VSOMEIP_INTERNAL_BASE_PORT; - VSOMEIP_INFO << "Routing endpoint at " << port; - #else - if (-1 == ::unlink(its_endpoint_path.c_str()) && errno != ENOENT) { - VSOMEIP_ERROR << "endpoint_manager_impl::create_local_server unlink failed (" - << its_endpoint_path << "): "<< std::strerror(errno); - } - VSOMEIP_INFO << __func__ << " Routing endpoint at " << its_endpoint_path; - #endif + auto its_address = configuration_->get_routing_host_address(); + auto its_port = configuration_->get_routing_host_port(); + + VSOMEIP_INFO << __func__ << ": Routing root @ " + << its_address.to_string() << ":" << std::dec << its_port; try { - its_endpoint = - std::make_shared ( - shared_from_this(), _routing_host, - #ifdef _WIN32 - boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port), - #else - boost::asio::local::stream_protocol_ext::endpoint(its_endpoint_path), - #endif - io_, - configuration_, true); + _root = + std::make_shared ( + shared_from_this(), _host, + boost::asio::ip::tcp::endpoint(its_address, its_port), + io_, configuration_, true); } catch (const std::exception &e) { - VSOMEIP_ERROR << "Server endpoint creation failed. Client ID: " + VSOMEIP_ERROR << "Remote routing root endpoint creation failed. Client ID: " << std::hex << std::setw(4) << std::setfill('0') << VSOMEIP_ROUTING_CLIENT << ": " << e.what(); + + return (false); } - *_is_socket_activated = false; + + _is_socket_activated = false; } - return its_endpoint; + + return (true); } instance_t endpoint_manager_impl::find_instance( @@ -807,8 +887,8 @@ void endpoint_manager_impl::on_disconnect(std::shared_ptr _endpoint) { if (!is_reliable) { static_cast(rm_)->on_availability( its_service.first, its_instance.first, - false, its_info->get_major(), - its_info->get_minor()); + availability_state_e::AS_UNAVAILABLE, + its_info->get_major(), its_info->get_minor()); } static_cast(rm_)->service_endpoint_disconnected( its_service.first, its_instance.first, @@ -820,7 +900,9 @@ void endpoint_manager_impl::on_disconnect(std::shared_ptr _endpoint) { } } -bool endpoint_manager_impl::on_bind_error(std::shared_ptr _endpoint, std::uint16_t _remote_port) { +bool endpoint_manager_impl::on_bind_error(std::shared_ptr _endpoint, + const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port) { + std::lock_guard its_ep_lock(endpoint_mutex_); for (auto &its_service : remote_services_) { for (auto &its_instance : its_service.second) { @@ -833,15 +915,16 @@ bool endpoint_manager_impl::on_bind_error(std::shared_ptr _endpoint, s uint16_t its_new_local_port(ILLEGAL_PORT); std::unique_lock its_lock(used_client_ports_mutex_); - if (configuration_->get_client_port(its_service.first, - its_instance.first, - _remote_port, - is_reliable, - used_client_ports_, - its_new_local_port)) { + std::map > its_used_client_ports; + get_used_client_ports(_remote_address, _remote_port, its_used_client_ports); + if (configuration_->get_client_port( + its_service.first, its_instance.first, + _remote_port, is_reliable, + its_used_client_ports, its_new_local_port)) { _endpoint->set_local_port(its_new_local_port); its_lock.unlock(); - release_port(its_old_local_port, _endpoint->is_reliable()); + release_used_client_port(_remote_address, _remote_port, + _endpoint->is_reliable(), its_old_local_port); return true; } } @@ -866,9 +949,43 @@ void endpoint_manager_impl::on_error( _receiver->is_reliable(), _receiver, _remote_address, _remote_port); } -void endpoint_manager_impl::release_port(uint16_t _port, bool _reliable) { +void +endpoint_manager_impl::get_used_client_ports( + const boost::asio::ip::address &_remote_address, port_t _remote_port, + std::map > &_used_ports) { + auto find_address = used_client_ports_.find(_remote_address); + if (find_address != used_client_ports_.end()) { + auto find_port = find_address->second.find(_remote_port); + if (find_port != find_address->second.end()) + _used_ports = find_port->second; + } +} + +void +endpoint_manager_impl::request_used_client_port( + const boost::asio::ip::address &_remote_address, port_t _remote_port, + bool _reliable, port_t _local_port) { + std::lock_guard its_lock(used_client_ports_mutex_); - used_client_ports_[_reliable].erase(_port); + used_client_ports_[_remote_address][_remote_port] + [_reliable].insert(_local_port); +} + +void +endpoint_manager_impl::release_used_client_port( + const boost::asio::ip::address &_remote_address, port_t _remote_port, + bool _reliable, port_t _local_port) { + + std::lock_guard its_lock(used_client_ports_mutex_); + auto find_address = used_client_ports_.find(_remote_address); + if (find_address != used_client_ports_.end()) { + auto find_port = find_address->second.find(_remote_port); + if (find_port != find_address->second.end()) { + auto find_reliable = find_port->second.find(_reliable); + if (find_reliable != find_port->second.end()) + find_reliable->second.erase(_local_port); + } + } } std::shared_ptr @@ -946,6 +1063,8 @@ std::shared_ptr endpoint_manager_impl::create_remote_client( std::shared_ptr its_endpoint; std::shared_ptr its_endpoint_def; uint16_t its_local_port; + + boost::asio::ip::address its_remote_address; uint16_t its_remote_port = ILLEGAL_PORT; auto found_service = remote_service_info_.find(_service); @@ -955,6 +1074,7 @@ std::shared_ptr endpoint_manager_impl::create_remote_client( auto found_reliability = found_instance->second.find(_reliable); if (found_reliability != found_instance->second.end()) { its_endpoint_def = found_reliability->second; + its_remote_address = its_endpoint_def->get_address(); its_remote_port = its_endpoint_def->get_port(); } } @@ -963,25 +1083,31 @@ std::shared_ptr endpoint_manager_impl::create_remote_client( if( its_remote_port != ILLEGAL_PORT) { // if client port range for remote service port range is configured // and remote port is in range, determine unused client port - std::unique_lock its_lock(used_client_ports_mutex_); - if (configuration_->get_client_port(_service, _instance, its_remote_port, _reliable, - used_client_ports_, its_local_port)) { - if(its_endpoint_def) { + std::map > its_used_client_ports; + { + std::lock_guard its_lock(used_client_ports_mutex_); + get_used_client_ports(its_remote_address, its_remote_port, its_used_client_ports); + } + if (configuration_->get_client_port(_service, _instance, + its_remote_port, _reliable, + its_used_client_ports, its_local_port)) { + if (its_endpoint_def) { its_endpoint = create_client_endpoint( - its_endpoint_def->get_address(), + its_remote_address, its_local_port, - its_endpoint_def->get_port(), + its_remote_port, _reliable); } if (its_endpoint) { - partition_id_t its_partition - = configuration_->get_partition_id(_service, _instance); - used_client_ports_[_reliable].insert(its_local_port); - its_lock.unlock(); + request_used_client_port(its_remote_address, its_remote_port, + _reliable, its_local_port); + service_instances_[_service][its_endpoint.get()] = _instance; remote_services_[_service][_instance][_reliable] = its_endpoint; + partition_id_t its_partition + = configuration_->get_partition_id(_service, _instance); client_endpoints_by_ip_[its_endpoint_def->get_address()] [its_endpoint_def->get_port()] [_reliable] @@ -1148,4 +1274,38 @@ endpoint_manager_impl::log_server_states() const { VSOMEIP_INFO << "ESQ: [" << its_log.str() << "]"; } +void +endpoint_manager_impl::add_multicast_option(const multicast_option_t &_option) { + + std::lock_guard its_guard(options_mutex_); + options_queue_.push(_option); + options_condition_.notify_one(); +} + +void +endpoint_manager_impl::process_multicast_options() { + + std::unique_lock its_lock(options_mutex_); + while (is_processing_options_) { + if (options_queue_.size() > 0) { + auto its_front = options_queue_.front(); + options_queue_.pop(); + auto its_udp_server_endpoint + = std::dynamic_pointer_cast(its_front.endpoint_); + if (its_udp_server_endpoint) { + // Unlock before setting the option as this might block + its_lock.unlock(); + its_udp_server_endpoint->set_multicast_option( + its_front.address_, its_front.is_join_); + // Lock again after setting the option + its_lock.lock(); + } + } else { + options_condition_.wait(its_lock, [this] { + return !options_queue_.empty() || !is_processing_options_; + }); + } + } +} + } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/local_client_endpoint_impl.cpp b/implementation/endpoints/src/local_client_endpoint_impl.cpp deleted file mode 100644 index 04c7787..0000000 --- a/implementation/endpoints/src/local_client_endpoint_impl.cpp +++ /dev/null @@ -1,413 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include - -#include - -#include -#include - -#include "../include/endpoint_host.hpp" -#include "../include/local_client_endpoint_impl.hpp" -#include "../include/local_server_endpoint_impl.hpp" -#include "../../routing/include/routing_host.hpp" -#include "../../security/include/security.hpp" - -// Credentials -#ifndef _WIN32 -#include "../include/credentials.hpp" -#endif - -namespace vsomeip_v3 { - -local_client_endpoint_impl::local_client_endpoint_impl( - const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, - const endpoint_type& _remote, - boost::asio::io_service &_io, - const std::shared_ptr& _configuration) - : local_client_endpoint_base_impl(_endpoint_host, _routing_host, _remote, - _remote, _io, - _configuration->get_max_message_size_local(), - _configuration->get_endpoint_queue_limit_local(), - _configuration), - // Using _remote for the local(!) endpoint is ok, - // because we have no bind for local endpoints! - recv_buffer_(VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE + 8,0) { - is_supporting_magic_cookies_ = false; -} - -local_client_endpoint_impl::~local_client_endpoint_impl() { - -} - -bool local_client_endpoint_impl::is_local() const { - return true; -} - -void local_client_endpoint_impl::restart(bool _force) { - if (!_force && state_ == cei_state_e::CONNECTING) { - return; - } - state_ = cei_state_e::CONNECTING; - { - std::lock_guard its_lock(mutex_); - sending_blocked_ = false; - queue_.clear(); - queue_size_ = 0; - } - { - std::lock_guard its_lock(socket_mutex_); - shutdown_and_close_socket_unlocked(true); - } - was_not_connected_ = true; - reconnect_counter_ = 0; - start_connect_timer(); -} - -void local_client_endpoint_impl::start() { - connect(); -} - -void local_client_endpoint_impl::stop() { - { - std::lock_guard its_lock(mutex_); - sending_blocked_ = true; - } - { - std::lock_guard its_lock(connect_timer_mutex_); - boost::system::error_code ec; - connect_timer_.cancel(ec); - } - connect_timeout_ = VSOMEIP_DEFAULT_CONNECT_TIMEOUT; - - bool is_open(false); - { - std::lock_guard its_lock(socket_mutex_); - is_open = socket_->is_open(); - } - if (is_open) { - bool send_queue_empty(false); - std::uint32_t times_slept(0); - - while (times_slept <= 50) { - mutex_.lock(); - send_queue_empty = (queue_.size() == 0); - mutex_.unlock(); - if (send_queue_empty) { - break; - } else { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - times_slept++; - } - } - } - shutdown_and_close_socket(false); -} - -void local_client_endpoint_impl::connect() { - boost::system::error_code its_connect_error; - { - std::lock_guard its_lock(socket_mutex_); - boost::system::error_code its_error; - socket_->open(remote_.protocol(), its_error); - - if (!its_error || its_error == boost::asio::error::already_open) { - socket_->set_option(boost::asio::socket_base::reuse_address(true), its_error); - if (its_error) { - VSOMEIP_WARNING << "local_client_endpoint_impl::connect: " - << "couldn't enable SO_REUSEADDR: " << its_error.message(); - } - state_ = cei_state_e::CONNECTING; - socket_->connect(remote_, its_connect_error); - -// Credentials -#ifndef _WIN32 - if (!its_connect_error) { - auto its_host = endpoint_host_.lock(); - if (its_host) { - credentials::send_credentials(socket_->native_handle(), - its_host->get_client()); - } - } else { - VSOMEIP_WARNING << "local_client_endpoint::connect: Couldn't " - << "connect to: " << remote_.path() << " (" - << its_connect_error.message() << " / " << std::dec - << its_connect_error.value() << ")"; - } -#endif - - } else { - VSOMEIP_WARNING << "local_client_endpoint::connect: Error opening socket: " - << its_error.message() << " (" << std::dec << its_error.value() - << ")"; - its_connect_error = its_error; - } - } - // call connect_cbk asynchronously - try { - strand_.post( - std::bind(&client_endpoint_impl::connect_cbk, shared_from_this(), - its_connect_error)); - } catch (const std::exception &e) { - VSOMEIP_ERROR << "local_client_endpoint_impl::connect: " << e.what(); - } -} - -void local_client_endpoint_impl::receive() { - std::lock_guard its_lock(socket_mutex_); - if (socket_->is_open()) { - socket_->async_receive( - boost::asio::buffer(recv_buffer_), - strand_.wrap( - std::bind( - &local_client_endpoint_impl::receive_cbk, - std::dynamic_pointer_cast< - local_client_endpoint_impl - >(shared_from_this()), - std::placeholders::_1, - std::placeholders::_2 - ) - ) - ); - } -} - -// this overrides client_endpoint_impl::send to disable the pull method -// for local communication -bool local_client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { - std::lock_guard its_lock(mutex_); - bool ret(true); - const bool queue_size_zero_on_entry(queue_.empty()); - if (endpoint_impl::sending_blocked_ || - check_message_size(nullptr, _size) != cms_ret_e::MSG_OK || - !check_packetizer_space(_size) || - !check_queue_limit(_data, _size)) { - ret = false; - } else { -#if 0 - std::stringstream msg; - msg << "lce::send: "; - for (uint32_t i = 0; i < _size; i++) - msg << std::hex << std::setw(2) << std::setfill('0') - << (int)_data[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - train_.buffer_->insert(train_.buffer_->end(), _data, _data + _size); - queue_train(queue_size_zero_on_entry); - } - return ret; -} - -void local_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { - static const byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 }; - static const byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 }; - std::vector bufs; - - bufs.push_back(boost::asio::buffer(its_start_tag)); - bufs.push_back(boost::asio::buffer(*_buffer)); - bufs.push_back(boost::asio::buffer(its_end_tag)); - - { - std::lock_guard its_lock(socket_mutex_); - boost::asio::async_write( - *socket_, - bufs, - std::bind( - &client_endpoint_impl::send_cbk, - std::dynamic_pointer_cast< - local_client_endpoint_impl - >(shared_from_this()), - std::placeholders::_1, - std::placeholders::_2, - _buffer - ) - ); - } -} - -void local_client_endpoint_impl::get_configured_times_from_endpoint( - service_t _service, method_t _method, - std::chrono::nanoseconds *_debouncing, - std::chrono::nanoseconds *_maximum_retention) const { - (void)_service; - (void)_method; - (void)_debouncing; - (void)_maximum_retention; - VSOMEIP_ERROR << "local_client_endpoint_impl::get_configured_times_from_endpoint called."; -} - -void local_client_endpoint_impl::send_magic_cookie() { -} - -void local_client_endpoint_impl::receive_cbk( - boost::system::error_code const &_error, std::size_t _bytes) { - if (_error) { - if (_error == boost::asio::error::operation_aborted) { - // endpoint was stopped - return; - } else if (_error == boost::asio::error::connection_reset - || _error == boost::asio::error::eof - || _error == boost::asio::error::bad_descriptor) { - VSOMEIP_TRACE << "local_client_endpoint:" - " connection_reseted/EOF/bad_descriptor"; - } else if (_error) { - VSOMEIP_ERROR << "Local endpoint received message (" - << _error.message() << ")"; - } - error_handler_t handler; - { - std::lock_guard its_lock(error_handler_mutex_); - handler = error_handler_; - } - if (handler) - handler(); - } else { - -#if 0 - std::stringstream msg; - msg << "lce<" << this << ">::recv: "; - for (std::size_t i = 0; i < recv_buffer_.size(); i++) - msg << std::setw(2) << std::setfill('0') << std::hex - << (int)recv_buffer_[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - - // We only handle a single message here. Check whether the message - // format matches what we do expect. - if (_bytes == VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE + 8 - && recv_buffer_[0] == 0x67 && recv_buffer_[1] == 0x37 - && recv_buffer_[2] == 0x6d && recv_buffer_[3] == 0x07 - && recv_buffer_[4] == VSOMEIP_ASSIGN_CLIENT_ACK - && recv_buffer_[13] == 0x07 && recv_buffer_[14] == 0x6d - && recv_buffer_[15] == 0x37 && recv_buffer_[16] == 0x67) { - - auto its_routing_host = routing_host_.lock(); - if (its_routing_host) - its_routing_host->on_message(&recv_buffer_[4], - static_cast(recv_buffer_.size() - 8), this); - } - - receive(); - } -} - -bool local_client_endpoint_impl::get_remote_address( - boost::asio::ip::address &_address) const { - (void)_address; - return false; -} - -std::uint16_t local_client_endpoint_impl::get_remote_port() const { - return 0; -} - -void local_client_endpoint_impl::set_local_port() { - // local_port_ is set to zero in ctor of client_endpoint_impl -> do nothing -} - -void local_client_endpoint_impl::print_status() { -#ifndef _WIN32 - std::string its_path = remote_.path(); -#else - std::string its_path(""); -#endif - std::size_t its_data_size(0); - std::size_t its_queue_size(0); - { - std::lock_guard its_lock(mutex_); - its_queue_size = queue_.size(); - its_data_size = queue_size_; - } - - VSOMEIP_INFO << "status lce: " << its_path << " queue: " - << its_queue_size << " data: " << its_data_size; -} - -std::string local_client_endpoint_impl::get_remote_information() const { -#ifdef _WIN32 - boost::system::error_code ec; - return remote_.address().to_string(ec) + ":" - + std::to_string(remote_.port()); -#else - return remote_.path(); -#endif -} - - -bool local_client_endpoint_impl::check_packetizer_space(std::uint32_t _size) { - if (train_.buffer_->size() + _size < train_.buffer_->size()) { - VSOMEIP_ERROR << "Overflow in packetizer addition ~> abort sending!"; - return false; - } - if (train_.buffer_->size() + _size > max_message_size_ - && !train_.buffer_->empty()) { - queue_.push_back(train_.buffer_); - queue_size_ += train_.buffer_->size(); - train_.buffer_ = std::make_shared(); - } - return true; -} - -bool local_client_endpoint_impl::is_reliable() const { - return false; -} - -std::uint32_t local_client_endpoint_impl::get_max_allowed_reconnects() const { - return 13; -} - -bool local_client_endpoint_impl::send(const std::vector& _cmd_header, - const byte_t *_data, uint32_t _size) { - std::lock_guard its_lock(mutex_); - bool ret(true); - const bool queue_size_zero_on_entry(queue_.empty()); - - const std::uint32_t its_complete_size = static_cast( - _cmd_header.size() + _size); - if (endpoint_impl::sending_blocked_ || - check_message_size(nullptr, its_complete_size) != cms_ret_e::MSG_OK || - !check_packetizer_space(its_complete_size)|| - !check_queue_limit(_data, its_complete_size)) { - ret = false; - } else { -#if 0 - std::stringstream msg; - msg << "lce::send: "; - for (uint32_t i = 0; i < _size; i++) - msg << std::hex << std::setw(2) << std::setfill('0') - << (int)_data[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - train_.buffer_->reserve(its_complete_size); - train_.buffer_->insert(train_.buffer_->end(), _cmd_header.begin(), _cmd_header.end()); - train_.buffer_->insert(train_.buffer_->end(), _data, _data + _size); - queue_train(queue_size_zero_on_entry); - } - return ret; -} - -bool local_client_endpoint_impl::tp_segmentation_enabled( - service_t _service, method_t _method) const { - (void)_service; - (void)_method; - return false; -} - -void local_client_endpoint_impl::max_allowed_reconnects_reached() { - VSOMEIP_ERROR << "local_client_endpoint::max_allowed_reconnects_reached: " - << get_remote_information(); - error_handler_t handler; - { - std::lock_guard its_lock(error_handler_mutex_); - handler = error_handler_; - } - if (handler) - handler(); -} - -} // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/local_server_endpoint_impl.cpp b/implementation/endpoints/src/local_server_endpoint_impl.cpp deleted file mode 100644 index ebf913f..0000000 --- a/implementation/endpoints/src/local_server_endpoint_impl.cpp +++ /dev/null @@ -1,993 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include - -#include -#include - -#include - -#include "../include/endpoint_host.hpp" -#include "../../routing/include/routing_host.hpp" -#include "../include/local_server_endpoint_impl.hpp" -#include "../../security/include/security.hpp" -#include "../../utility/include/byteorder.hpp" -#include "../../configuration/include/configuration.hpp" -#include "../../utility/include/utility.hpp" - -// Credentials -#ifndef _WIN32 -#include "../include/credentials.hpp" -#endif - -namespace vsomeip_v3 { - -local_server_endpoint_impl::local_server_endpoint_impl( - const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, - const endpoint_type& _local, boost::asio::io_service &_io, - const std::shared_ptr& _configuration, - bool _is_routing_endpoint) - : local_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, - _io, - _configuration->get_max_message_size_local(), - _configuration->get_endpoint_queue_limit_local(), - _configuration), - acceptor_(_io), - buffer_shrink_threshold_(_configuration->get_buffer_shrink_threshold()), - is_routing_endpoint_(_is_routing_endpoint) { - is_supporting_magic_cookies_ = false; - - boost::system::error_code ec; - acceptor_.open(_local.protocol(), ec); - boost::asio::detail::throw_error(ec, "acceptor open"); - acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "acceptor set_option"); - acceptor_.bind(_local, ec); - boost::asio::detail::throw_error(ec, "acceptor bind"); - acceptor_.listen(boost::asio::socket_base::max_connections, ec); - boost::asio::detail::throw_error(ec, "acceptor listen"); - -#ifndef _WIN32 - if (chmod(_local.path().c_str(), - static_cast(_configuration->get_permissions_uds())) == -1) { - VSOMEIP_ERROR << __func__ << ": chmod: " << strerror(errno); - } - credentials::activate_credentials(acceptor_.native_handle()); -#endif -} - -local_server_endpoint_impl::local_server_endpoint_impl( - const std::shared_ptr& _endpoint_host, - const std::shared_ptr& _routing_host, - const endpoint_type& _local, boost::asio::io_service &_io, - int native_socket, - const std::shared_ptr& _configuration, - bool _is_routing_endpoint) - : local_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, _io, - _configuration->get_max_message_size_local(), - _configuration->get_endpoint_queue_limit_local(), - _configuration), - acceptor_(_io), - buffer_shrink_threshold_(configuration_->get_buffer_shrink_threshold()), - is_routing_endpoint_(_is_routing_endpoint) { - is_supporting_magic_cookies_ = false; - - boost::system::error_code ec; - acceptor_.assign(_local.protocol(), native_socket, ec); - boost::asio::detail::throw_error(ec, "acceptor assign native socket"); - -#ifndef _WIN32 - if (chmod(_local.path().c_str(), - static_cast(_configuration->get_permissions_uds())) == -1) { - VSOMEIP_ERROR << __func__ << ": chmod: " << strerror(errno); - } - credentials::activate_credentials(acceptor_.native_handle()); -#endif -} - -local_server_endpoint_impl::~local_server_endpoint_impl() { -} - -bool local_server_endpoint_impl::is_local() const { - return true; -} - -void local_server_endpoint_impl::start() { - std::lock_guard its_lock(acceptor_mutex_); - if (acceptor_.is_open()) { - connection::ptr new_connection = connection::create( - std::dynamic_pointer_cast( - shared_from_this()), max_message_size_, - buffer_shrink_threshold_, - service_); - - { - std::unique_lock its_lock(new_connection->get_socket_lock()); - acceptor_.async_accept( - new_connection->get_socket(), - std::bind( - &local_server_endpoint_impl::accept_cbk, - std::dynamic_pointer_cast< - local_server_endpoint_impl - >(shared_from_this()), - new_connection, - std::placeholders::_1 - ) - ); - } - } -} - -void local_server_endpoint_impl::stop() { - server_endpoint_impl::stop(); - { - std::lock_guard its_lock(acceptor_mutex_); - if (acceptor_.is_open()) { - boost::system::error_code its_error; - acceptor_.close(its_error); - } - } - { - std::lock_guard its_lock(connections_mutex_); - for (const auto &c : connections_) { - c.second->stop(); - } - connections_.clear(); - } -} - -bool local_server_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { -#if 0 - std::stringstream msg; - msg << "lse::send "; - for (uint32_t i = 0; i < _size; i++) - msg << std::setw(2) << std::setfill('0') << std::hex << (int)_data[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - std::lock_guard its_lock(mutex_); - if (endpoint_impl::sending_blocked_) { - return false; - } - - client_t its_client; - std::memcpy(&its_client, &_data[7], sizeof(its_client)); - - connection::ptr its_connection; - { - std::lock_guard its_lock(connections_mutex_); - const auto its_iterator = connections_.find(its_client); - if (its_iterator == connections_.end()) { - return false; - } else { - its_connection = its_iterator->second; - } - } - - auto its_buffer = std::make_shared(); - its_buffer->insert(its_buffer->end(), _data, _data + _size); - its_connection->send_queued(its_buffer); - - return true; -} - -bool local_server_endpoint_impl::send_to( - const std::shared_ptr _target, - const byte_t *_data, uint32_t _size) { - (void)_target; - (void)_data; - (void)_size; - return false; -} - -bool local_server_endpoint_impl::send_error( - const std::shared_ptr _target, - const byte_t *_data, uint32_t _size) { - (void)_target; - (void)_data; - (void)_size; - return false; -} - -void local_server_endpoint_impl::send_queued( - const queue_iterator_type _queue_iterator) { - (void)_queue_iterator; -} - -void local_server_endpoint_impl::receive() { - // intentionally left empty -} - -bool local_server_endpoint_impl::get_default_target( - service_t, - local_server_endpoint_impl::endpoint_type &) const { - return false; -} - -bool local_server_endpoint_impl::add_connection(const client_t &_client, - const std::shared_ptr &_connection) { - bool ret = false; - std::lock_guard its_lock(connections_mutex_); - auto find_connection = connections_.find(_client); - if (find_connection == connections_.end()) { - connections_[_client] = _connection; - ret = true; - } else { - VSOMEIP_WARNING << "Attempt to add already existing " - "connection to client " << std::hex << _client; - } - return ret; -} - -void local_server_endpoint_impl::remove_connection( - const client_t &_client) { - std::lock_guard its_lock(connections_mutex_); - connections_.erase(_client); -} - -void local_server_endpoint_impl::accept_cbk( - const connection::ptr& _connection, boost::system::error_code const &_error) { - if (_error != boost::asio::error::bad_descriptor - && _error != boost::asio::error::operation_aborted - && _error != boost::asio::error::no_descriptors) { - start(); - } else if (_error == boost::asio::error::no_descriptors) { - VSOMEIP_ERROR << "local_server_endpoint_impl::accept_cbk: " - << _error.message() << " (" << std::dec << _error.value() - << ") Will try to accept again in 1000ms"; - std::shared_ptr its_timer = - std::make_shared(service_, - std::chrono::milliseconds(1000)); - auto its_ep = std::dynamic_pointer_cast( - shared_from_this()); - its_timer->async_wait([its_timer, its_ep] - (const boost::system::error_code& _error) { - if (!_error) { - its_ep->start(); - } - }); - } - - if (!_error) { -#ifndef _WIN32 - auto its_host = endpoint_host_.lock(); - client_t client = 0; - - socket_type &new_connection_socket = _connection->get_socket(); - uid_t uid(ANY_UID); - gid_t gid(ANY_GID); - client = credentials::receive_credentials( - new_connection_socket.native_handle(), uid, gid); - - if (its_host && security::get()->is_enabled()) { - if (!configuration_->check_routing_credentials(client, uid, gid)) { - VSOMEIP_WARNING << "vSomeIP Security: Rejecting new connection with routing manager client ID 0x" << std::hex << client - << " uid/gid= " << std::dec << uid << "/" << gid - << " because passed credentials do not match with routing manager credentials!"; - boost::system::error_code er; - new_connection_socket.shutdown(new_connection_socket.shutdown_both, er); - new_connection_socket.close(er); - return; - } - - if (is_routing_endpoint_) { - // rm_impl receives VSOMEIP_CLIENT_UNSET initially -> check later - _connection->set_bound_uid_gid(uid, gid); - } else { - { - std::lock_guard its_connection_lock(connections_mutex_); - // rm_impl receives VSOMEIP_CLIENT_UNSET initially -> check later - const auto found_client = connections_.find(client); - if (found_client != connections_.end()) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex - << its_host->get_client() << " is rejecting new connection with client ID 0x" - << client << " uid/gid= " << std::dec << uid << "/" << gid - << " because of already existing connection using same client ID"; - boost::system::error_code er; - new_connection_socket.shutdown(new_connection_socket.shutdown_both, er); - new_connection_socket.close(er); - return; - } - } - if (!security::get()->check_credentials(client, uid, gid)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex - << its_host->get_client() << " received client credentials from client 0x" - << client << " which violates the security policy : uid/gid=" - << std::dec << uid << "/" << gid; - boost::system::error_code er; - new_connection_socket.shutdown(new_connection_socket.shutdown_both, er); - new_connection_socket.close(er); - return; - } - // rm_impl receives VSOMEIP_CLIENT_UNSET initially -> set later - _connection->set_bound_client(client); - add_connection(client, _connection); - } - } else { - security::get()->store_client_to_uid_gid_mapping(client, uid, gid); - security::get()->store_uid_gid_to_client_mapping(uid, gid, client); - } -#endif - _connection->start(); - } -} - -/////////////////////////////////////////////////////////////////////////////// -// class local_service_impl::connection -/////////////////////////////////////////////////////////////////////////////// - -local_server_endpoint_impl::connection::connection( - const std::shared_ptr& _server, - std::uint32_t _max_message_size, - std::uint32_t _initial_recv_buffer_size, - std::uint32_t _buffer_shrink_threshold, - boost::asio::io_service &_io_service) - : socket_(_io_service), - server_(_server), - recv_buffer_size_initial_(_initial_recv_buffer_size + 8), - max_message_size_(_max_message_size), - recv_buffer_(recv_buffer_size_initial_, 0), - recv_buffer_size_(0), - missing_capacity_(0), - shrink_count_(0), - buffer_shrink_threshold_(_buffer_shrink_threshold), - bound_client_(VSOMEIP_CLIENT_UNSET), -#ifndef _WIN32 - bound_uid_(ANY_UID), - bound_gid_(ANY_GID), -#endif - assigned_client_(false) { - if (_server->is_routing_endpoint_ && - !security::get()->is_enabled()) { - assigned_client_ = true; - } -} - -local_server_endpoint_impl::connection::ptr -local_server_endpoint_impl::connection::create( - const std::shared_ptr& _server, - std::uint32_t _max_message_size, - std::uint32_t _buffer_shrink_threshold, - boost::asio::io_service &_io_service) { - const std::uint32_t its_initial_buffer_size = VSOMEIP_COMMAND_HEADER_SIZE - + static_cast(sizeof(instance_t) + sizeof(bool) - + sizeof(bool)); - return ptr(new connection(_server, _max_message_size, its_initial_buffer_size, - _buffer_shrink_threshold, _io_service)); -} - -local_server_endpoint_impl::socket_type & -local_server_endpoint_impl::connection::get_socket() { - return socket_; -} - -std::unique_lock -local_server_endpoint_impl::connection::get_socket_lock() { - return std::unique_lock(socket_mutex_); -} - -void local_server_endpoint_impl::connection::start() { - std::lock_guard its_lock(socket_mutex_); - if (socket_.is_open()) { - const std::size_t its_capacity(recv_buffer_.capacity()); - size_t buffer_size = its_capacity - recv_buffer_size_; - try { - if (missing_capacity_) { - if (missing_capacity_ > MESSAGE_SIZE_UNLIMITED) { - VSOMEIP_ERROR << "Missing receive buffer capacity exceeds allowed maximum!"; - return; - } - const std::size_t its_required_capacity(recv_buffer_size_ + missing_capacity_); - if (its_capacity < its_required_capacity) { - recv_buffer_.reserve(its_required_capacity); - recv_buffer_.resize(its_required_capacity, 0x0); - } - buffer_size = missing_capacity_; - missing_capacity_ = 0; - } else if (buffer_shrink_threshold_ - && shrink_count_ > buffer_shrink_threshold_ - && recv_buffer_size_ == 0) { - recv_buffer_.resize(recv_buffer_size_initial_, 0x0); - recv_buffer_.shrink_to_fit(); - buffer_size = recv_buffer_size_initial_; - shrink_count_ = 0; - } - } catch (const std::exception &e) { - handle_recv_buffer_exception(e); - // don't start receiving again - return; - } -#ifndef _WIN32 - socket_.async_receive( - boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size), - std::bind( - &local_server_endpoint_impl::connection::receive_cbk, - shared_from_this(), - std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3, - std::placeholders::_4 - ) - ); -#else - socket_.async_receive( - boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size), - std::bind( - &local_server_endpoint_impl::connection::receive_cbk, - shared_from_this(), - std::placeholders::_1, - std::placeholders::_2 - ) - ); -#endif - } -} - -void local_server_endpoint_impl::connection::stop() { - std::lock_guard its_lock(socket_mutex_); - if (socket_.is_open()) { -#ifndef _WIN32 - if (-1 == fcntl(socket_.native_handle(), F_GETFD)) { - VSOMEIP_ERROR << "lse: socket/handle closed already '" << std::string(std::strerror(errno)) - << "' (" << errno << ") " << get_path_local(); - } -#endif - boost::system::error_code its_error; - socket_.shutdown(socket_.shutdown_both, its_error); - socket_.close(its_error); - } -} - -void local_server_endpoint_impl::connection::send_queued( - const message_buffer_ptr_t& _buffer) { - std::shared_ptr its_server(server_.lock()); - if (!its_server) { - VSOMEIP_TRACE << "local_server_endpoint_impl::connection::send_queued " - " couldn't lock server_"; - return; - } - - static const byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 }; - static const byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 }; - std::vector bufs; - -#if 0 - std::stringstream msg; - msg << "lse::sq: "; - for (std::size_t i = 0; i < _buffer->size(); i++) - msg << std::setw(2) << std::setfill('0') << std::hex - << (int)(*_buffer)[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - - bufs.push_back(boost::asio::buffer(its_start_tag)); - bufs.push_back(boost::asio::buffer(*_buffer)); - bufs.push_back(boost::asio::buffer(its_end_tag)); - - { - std::lock_guard its_lock(socket_mutex_); - boost::asio::async_write( - socket_, - bufs, - std::bind( - &local_server_endpoint_impl::connection::send_cbk, - shared_from_this(), - _buffer, - std::placeholders::_1, - std::placeholders::_2 - ) - ); - } -} - -client_t local_server_endpoint_impl::assign_client( - const byte_t *_data, uint32_t _size) { - client_t its_client(VSOMEIP_CLIENT_UNSET); - std::string its_name; - uint32_t its_name_length; - - if (_size >= VSOMEIP_COMMAND_PAYLOAD_POS) { - std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS], sizeof(its_client)); - std::memcpy(&its_name_length, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN], - sizeof(its_name_length)); - - if (its_name_length > 0) - its_name.assign(reinterpret_cast( - &_data[VSOMEIP_COMMAND_PAYLOAD_POS]), its_name_length); - } - - its_client = utility::request_client_id(configuration_, its_name, its_client); - - return its_client; -} - -void local_server_endpoint_impl::get_configured_times_from_endpoint( - service_t _service, - method_t _method, std::chrono::nanoseconds *_debouncing, - std::chrono::nanoseconds *_maximum_retention) const { - (void)_service; - (void)_method; - (void)_debouncing; - (void)_maximum_retention; - VSOMEIP_ERROR << "local_server_endpoint_impl::get_configured_times_from_endpoint."; -} - -void local_server_endpoint_impl::connection::send_cbk(const message_buffer_ptr_t _buffer, - boost::system::error_code const &_error, std::size_t _bytes) { - (void)_buffer; - (void)_bytes; - if (_error) - VSOMEIP_WARNING << "sei::send_cbk received error: " << _error.message(); -} - -void local_server_endpoint_impl::connection::receive_cbk( - boost::system::error_code const &_error, std::size_t _bytes -#ifndef _WIN32 - , std::uint32_t const &_uid, std::uint32_t const &_gid -#endif - ) -{ - std::shared_ptr its_server(server_.lock()); - if (!its_server) { - VSOMEIP_TRACE << "local_server_endpoint_impl::connection::receive_cbk " - " couldn't lock server_"; - return; - } - - std::shared_ptr its_host = its_server->routing_host_.lock(); - if (!its_host) - return; - - if (_error == boost::asio::error::operation_aborted) { - if (its_server->is_routing_endpoint_ && - bound_client_ != VSOMEIP_CLIENT_UNSET) { - utility::release_client_id(bound_client_); - set_bound_client(VSOMEIP_CLIENT_UNSET); - } - - // connection was stopped - return; - } - - bool is_error(false); - std::size_t its_start = 0; - std::size_t its_end = 0; - std::size_t its_iteration_gap = 0; - std::uint32_t its_command_size = 0; - - if (!_error && 0 < _bytes) { -#if 0 - std::stringstream msg; - msg << "lse::c<" << this << ">rcb: "; - for (std::size_t i = 0; i < _bytes + recv_buffer_size_; i++) - msg << std::setw(2) << std::setfill('0') << std::hex - << (int) (recv_buffer_[i]) << " "; - VSOMEIP_INFO << msg.str(); -#endif - - if (recv_buffer_size_ + _bytes < recv_buffer_size_) { - VSOMEIP_ERROR << "receive buffer overflow in local server endpoint ~> abort!"; - return; - } - recv_buffer_size_ += _bytes; - - bool message_is_empty(false); - bool found_message(false); - - do { - found_message = false; - message_is_empty = false; - - its_start = 0 + its_iteration_gap; - if (its_start + 3 < its_start) { - VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; - return; - } - while (its_start + 3 < recv_buffer_size_ + its_iteration_gap && - (recv_buffer_[its_start] != 0x67 || - recv_buffer_[its_start+1] != 0x37 || - recv_buffer_[its_start+2] != 0x6d || - recv_buffer_[its_start+3] != 0x07)) { - its_start++; - } - - if (its_start + 3 == recv_buffer_size_ + its_iteration_gap) { - message_is_empty = true; - } else { - its_start += 4; - } - - if (!message_is_empty) { - if (its_start + 6 < recv_buffer_size_ + its_iteration_gap) { - its_command_size = VSOMEIP_BYTES_TO_LONG( - recv_buffer_[its_start + 6], - recv_buffer_[its_start + 5], - recv_buffer_[its_start + 4], - recv_buffer_[its_start + 3]); - - its_end = its_start + 6 + its_command_size; - } else { - its_end = its_start; - } - if (its_command_size && max_message_size_ != MESSAGE_SIZE_UNLIMITED - && its_command_size > max_message_size_) { - std::lock_guard its_lock(socket_mutex_); - VSOMEIP_ERROR << "Received a local message which exceeds " - << "maximum message size (" << std::dec << its_command_size - << ") aborting! local: " << get_path_local() << " remote: " - << get_path_remote(); - recv_buffer_.resize(recv_buffer_size_initial_, 0x0); - recv_buffer_.shrink_to_fit(); - return; - } - if (its_end + 3 < its_end) { - VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; - return; - } - while (its_end + 3 < recv_buffer_size_ + its_iteration_gap && - (recv_buffer_[its_end] != 0x07 || - recv_buffer_[its_end+1] != 0x6d || - recv_buffer_[its_end+2] != 0x37 || - recv_buffer_[its_end+3] != 0x67)) { - its_end ++; - } - if (its_end + 4 < its_end) { - VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; - return; - } - // check if we received a full message - if (recv_buffer_size_ + its_iteration_gap < its_end + 4 - || recv_buffer_[its_end] != 0x07 - || recv_buffer_[its_end+1] != 0x6d - || recv_buffer_[its_end+2] != 0x37 - || recv_buffer_[its_end+3] != 0x67) { - // command (1 Byte) + client id (2 Byte) - // + command size (4 Byte) + data itself + stop tag (4 byte) - // = 11 Bytes not covered in command size. - if (its_start - its_iteration_gap + its_command_size + 11 > recv_buffer_size_) { - missing_capacity_ = - std::uint32_t(its_start) - std::uint32_t(its_iteration_gap) - + its_command_size + 11 - std::uint32_t(recv_buffer_size_); - } else if (recv_buffer_size_ < 11) { - // to little data to read out the command size - // minimal amount of data needed to read out command size = 11 - missing_capacity_ = 11 - static_cast(recv_buffer_size_); - } else { - std::stringstream local_msg; - for (std::size_t i = its_iteration_gap; - i < recv_buffer_size_ + its_iteration_gap && - i - its_iteration_gap < 32; i++) { - local_msg << std::setw(2) << std::setfill('0') - << std::hex << (int) recv_buffer_[i] << " "; - } - VSOMEIP_ERROR << "lse::c<" << this - << ">rcb: recv_buffer_size is: " << std::dec - << recv_buffer_size_ << " but couldn't read " - "out command size. recv_buffer_capacity: " - << std::dec << recv_buffer_.capacity() - << " its_iteration_gap: " << std::dec - << its_iteration_gap << " bound client: 0x" - << std::hex << bound_client_ << " buffer: " - << local_msg.str(); - recv_buffer_size_ = 0; - missing_capacity_ = 0; - its_iteration_gap = 0; - message_is_empty = true; - } - } - } - - if (!message_is_empty && - its_end + 3 < recv_buffer_size_ + its_iteration_gap) { - - if (its_server->is_routing_endpoint_ - && recv_buffer_[its_start] == VSOMEIP_ASSIGN_CLIENT) { - client_t its_client = its_server->assign_client( - &recv_buffer_[its_start], uint32_t(its_end - its_start)); -#ifndef _WIN32 - if (security::get()->is_enabled()) { - if (!its_server->add_connection(its_client, shared_from_this())) { - VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() - << " is rejecting new connection with client ID 0x" << its_client - << " uid/gid= " << std::dec << bound_uid_ << "/" << bound_gid_ - << " because of already existing connection using same client ID"; - stop(); - return; - } else if (!security::get()->check_credentials( - its_client, bound_uid_, bound_gid_)) { - VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() - << " received client credentials from client 0x" << its_client - << " which violates the security policy : uid/gid=" - << std::dec << bound_uid_ << "/" << bound_gid_; - its_server->remove_connection(its_client); - utility::release_client_id(its_client); - stop(); - return; - } else { - set_bound_client(its_client); - } - } else -#endif - { - set_bound_client(its_client); - its_server->add_connection(its_client, shared_from_this()); - } - its_server->send_client_identifier(its_client); - assigned_client_ = true; - } else if (!its_server->is_routing_endpoint_ || assigned_client_) { -#ifndef _WIN32 - credentials_t its_credentials = std::make_pair(_uid, _gid); -#else - credentials_t its_credentials = std::make_pair(ANY_UID, ANY_GID); -#endif - its_host->on_message(&recv_buffer_[its_start], - uint32_t(its_end - its_start), its_server.get(), - boost::asio::ip::address(), bound_client_, its_credentials); - } else { - VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() - << " didn't receive VSOMEIP_ASSIGN_CLIENT as first message"; - } - #if 0 - std::stringstream local_msg; - local_msg << "lse::c<" << this << ">rcb::thunk: "; - for (std::size_t i = its_start; i < its_end; i++) - local_msg << std::setw(2) << std::setfill('0') << std::hex - << (int) recv_buffer_[i] << " "; - VSOMEIP_INFO << local_msg.str(); - #endif - calculate_shrink_count(); - recv_buffer_size_ -= (its_end + 4 - its_iteration_gap); - missing_capacity_ = 0; - its_command_size = 0; - found_message = true; - its_iteration_gap = its_end + 4; - } else { - if (its_iteration_gap) { - // Message not complete and not in front of the buffer! - // Copy last part to front for consume in future receive_cbk call! - for (size_t i = 0; i < recv_buffer_size_; ++i) { - recv_buffer_[i] = recv_buffer_[i + its_iteration_gap]; - } - // Still more capacity needed after shifting everything to front? - if (missing_capacity_ && - missing_capacity_ <= recv_buffer_.capacity() - recv_buffer_size_) { - missing_capacity_ = 0; - } - } else if (message_is_empty) { - VSOMEIP_ERROR << "Received garbage data."; - is_error = true; - } - } - } while (recv_buffer_size_ > 0 && found_message); - } - - if (_error == boost::asio::error::eof - || _error == boost::asio::error::connection_reset - || is_error) { - stop(); - its_server->remove_connection(bound_client_); - security::get()->remove_client_to_uid_gid_mapping(bound_client_); - } else if (_error != boost::asio::error::bad_descriptor) { - start(); - } -} - -void local_server_endpoint_impl::connection::set_bound_client(client_t _client) { - bound_client_ = _client; -} - -client_t local_server_endpoint_impl::connection::get_bound_client() const { - return bound_client_; -} - -#ifndef _WIN32 -void local_server_endpoint_impl::connection::set_bound_uid_gid(uid_t _uid, gid_t _gid) { - bound_uid_ = _uid; - bound_gid_ = _gid; -} -#endif - -void local_server_endpoint_impl::connection::calculate_shrink_count() { - if (buffer_shrink_threshold_) { - if (recv_buffer_.capacity() != recv_buffer_size_initial_) { - if (recv_buffer_size_ < (recv_buffer_.capacity() >> 1)) { - shrink_count_++; - } else { - shrink_count_ = 0; - } - } - } -} - -const std::string local_server_endpoint_impl::connection::get_path_local() const { - boost::system::error_code ec; - std::string its_local_path; - if (socket_.is_open()) { - endpoint_type its_local_endpoint = socket_.local_endpoint(ec); - if (!ec) { -#ifdef _WIN32 - its_local_path += its_local_endpoint.address().to_string(ec); - its_local_path += ":"; - its_local_path += std::to_string(its_local_endpoint.port()); -#else - its_local_path += its_local_endpoint.path(); -#endif - - } - } - return its_local_path; -} - -const std::string local_server_endpoint_impl::connection::get_path_remote() const { - boost::system::error_code ec; - std::string its_remote_path; - if (socket_.is_open()) { - endpoint_type its_remote_endpoint = socket_.remote_endpoint(ec); - if (!ec) { -#ifdef _WIN32 - its_remote_path += its_remote_endpoint.address().to_string(ec); - its_remote_path += ":"; - its_remote_path += std::to_string(its_remote_endpoint.port()); -#else - its_remote_path += its_remote_endpoint.path(); -#endif - } - } - return its_remote_path; -} - -void local_server_endpoint_impl::connection::handle_recv_buffer_exception( - const std::exception &_e) { - std::stringstream its_message; - its_message <<"local_server_endpoint_impl::connection catched exception" - << _e.what() << " local: " << get_path_local() << " remote: " - << get_path_remote() << " shutting down connection. Start of buffer: "; - - for (std::size_t i = 0; i < recv_buffer_size_ && i < 16; i++) { - its_message << std::setw(2) << std::setfill('0') << std::hex - << (int) (recv_buffer_[i]) << " "; - } - - its_message << " Last 16 Bytes captured: "; - for (int i = 15; recv_buffer_size_ > 15u && i >= 0; i--) { - its_message << std::setw(2) << std::setfill('0') << std::hex - << (int) (recv_buffer_[static_cast(i)]) << " "; - } - VSOMEIP_ERROR << its_message.str(); - recv_buffer_.clear(); - if (socket_.is_open()) { -#ifndef _WIN32 - if (-1 == fcntl(socket_.native_handle(), F_GETFD)) { - VSOMEIP_ERROR << "lse: socket/handle closed already '" << std::string(std::strerror(errno)) - << "' (" << errno << ") " << get_path_local(); - } -#endif - boost::system::error_code its_error; - socket_.shutdown(socket_.shutdown_both, its_error); - socket_.close(its_error); - } - std::shared_ptr its_server = server_.lock(); - if (its_server) { - its_server->remove_connection(bound_client_); - } -} - -std::size_t -local_server_endpoint_impl::connection::get_recv_buffer_capacity() const { - return recv_buffer_.capacity(); -} - -void local_server_endpoint_impl::print_status() { - std::lock_guard its_lock(mutex_); - connections_t its_connections; - { - std::lock_guard its_lock(connections_mutex_); - its_connections = connections_; - } -#ifndef _WIN32 - std::string its_local_path(local_.path()); -#else - std::string its_local_path(""); -#endif - VSOMEIP_INFO << "status lse: " << its_local_path << " connections: " - << std::dec << its_connections.size() << " queues: " - << std::dec << queues_.size(); - for (const auto &c : its_connections) { -#ifndef _WIN32 - std::string its_remote_path; // TODO: construct the path -#else - std::string its_remote_path(""); -#endif - - std::size_t its_recv_size(0); - { - std::unique_lock c_s_lock(c.second->get_socket_lock()); - its_recv_size = c.second->get_recv_buffer_capacity(); - } - - VSOMEIP_INFO << "status lse: client: " << its_remote_path - << " recv_buffer: " << std::dec << its_recv_size; - } -} -std::string local_server_endpoint_impl::get_remote_information( - const queue_iterator_type _queue_iterator) const { -#ifdef _WIN32 - boost::system::error_code ec; - return _queue_iterator->first.address().to_string(ec) + ":" - + std::to_string(_queue_iterator->first.port()); -#else - (void)_queue_iterator; - return "local"; -#endif -} - -std::string local_server_endpoint_impl::get_remote_information( - const endpoint_type& _remote) const { -#ifdef _WIN32 - boost::system::error_code ec; - return _remote.address().to_string(ec) + ":" - + std::to_string(_remote.port()); -#else - (void)_remote; - return "local"; -#endif -} - -bool local_server_endpoint_impl::is_reliable() const { - return false; -} - -std::uint16_t local_server_endpoint_impl::get_local_port() const { - return 0; -} - -void local_server_endpoint_impl::set_local_port(std::uint16_t _port) { - (void) _port; -} - -bool local_server_endpoint_impl::check_packetizer_space( - queue_iterator_type _queue_iterator, message_buffer_ptr_t* _packetizer, - std::uint32_t _size) { - if ((*_packetizer)->size() + _size < (*_packetizer)->size()) { - VSOMEIP_ERROR << "Overflow in packetizer addition ~> abort sending!"; - return false; - } - if ((*_packetizer)->size() + _size > max_message_size_ - && !(*_packetizer)->empty()) { - _queue_iterator->second.second.push_back(*_packetizer); - _queue_iterator->second.first += (*_packetizer)->size(); - *_packetizer = std::make_shared(); - } - return true; -} - -void -local_server_endpoint_impl::send_client_identifier( - const client_t &_client) { - byte_t its_command[] = { - VSOMEIP_ASSIGN_CLIENT_ACK, - 0x0, 0x0, // client - 0x2, 0x0, 0x0, 0x0, // size - 0x0, 0x0 // assigned client - }; - - std::memcpy(its_command+7, &_client, sizeof(_client)); - - send(its_command, sizeof(its_command)); -} - - -bool local_server_endpoint_impl::tp_segmentation_enabled( - service_t _service, method_t _method) const { - (void)_service; - (void)_method; - return false; -} - - -} // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/local_tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/local_tcp_client_endpoint_impl.cpp new file mode 100644 index 0000000..e728827 --- /dev/null +++ b/implementation/endpoints/src/local_tcp_client_endpoint_impl.cpp @@ -0,0 +1,382 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include + +#include + +#include +#include + +#include "../include/endpoint_host.hpp" +#include "../include/local_tcp_client_endpoint_impl.hpp" +#include "../include/local_tcp_server_endpoint_impl.hpp" +#include "../../protocol/include/protocol.hpp" +#include "../../routing/include/routing_host.hpp" + +namespace vsomeip_v3 { + +local_tcp_client_endpoint_impl::local_tcp_client_endpoint_impl( + const std::shared_ptr &_endpoint_host, + const std::shared_ptr &_routing_host, + const endpoint_type & _local, + const endpoint_type &_remote, + boost::asio::io_context &_io, + const std::shared_ptr &_configuration) + : local_tcp_client_endpoint_base_impl(_endpoint_host, _routing_host, + _local, _remote, _io, + _configuration->get_max_message_size_local(), + _configuration->get_endpoint_queue_limit_local(), + _configuration), + recv_buffer_(VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE, 0) { + + is_supporting_magic_cookies_ = false; +} + +local_tcp_client_endpoint_impl::~local_tcp_client_endpoint_impl() { + +} + +bool local_tcp_client_endpoint_impl::is_local() const { + + return true; +} + +void local_tcp_client_endpoint_impl::restart(bool _force) { + + if (!_force && state_ == cei_state_e::CONNECTING) { + return; + } + state_ = cei_state_e::CONNECTING; + { + std::lock_guard its_lock(mutex_); + sending_blocked_ = false; + queue_.clear(); + queue_size_ = 0; + } + { + std::lock_guard its_lock(socket_mutex_); + shutdown_and_close_socket_unlocked(true); + } + was_not_connected_ = true; + reconnect_counter_ = 0; + start_connect_timer(); +} + +void local_tcp_client_endpoint_impl::start() { + + { + std::lock_guard its_lock(mutex_); + sending_blocked_ = false; + } + connect(); +} + +void local_tcp_client_endpoint_impl::stop() { + { + std::lock_guard its_lock(mutex_); + sending_blocked_ = true; + } + { + std::lock_guard its_lock(connect_timer_mutex_); + boost::system::error_code ec; + connect_timer_.cancel(ec); + } + connect_timeout_ = VSOMEIP_DEFAULT_CONNECT_TIMEOUT; + + bool is_open(false); + { + std::lock_guard its_lock(socket_mutex_); + is_open = socket_->is_open(); + } + if (is_open) { + bool send_queue_empty(false); + std::uint32_t times_slept(0); + + while (times_slept <= 50) { + mutex_.lock(); + send_queue_empty = (queue_.size() == 0); + mutex_.unlock(); + if (send_queue_empty) { + break; + } else { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + times_slept++; + } + } + } + shutdown_and_close_socket(false); +} + +void local_tcp_client_endpoint_impl::connect() { + start_connecting_timer(); + boost::system::error_code its_connect_error; + { + std::lock_guard its_lock(socket_mutex_); + boost::system::error_code its_error; + socket_->open(remote_.protocol(), its_error); + + if (!its_error || its_error == boost::asio::error::already_open) { + socket_->set_option(boost::asio::socket_base::reuse_address(true), its_error); + if (its_error) { + VSOMEIP_WARNING << "local_tcp_client_endpoint_impl::" << __func__ + << ": Cannot enable SO_REUSEADDR" + << "(" << its_error.message() << ")"; + } + + socket_->bind(local_, its_error); + if (its_error) { + VSOMEIP_WARNING << "local_tcp_client_endpoint_impl::" << __func__ + << ": Cannot bind to client port " << local_.port() + << "(" << its_error.message() << ")"; + } + + state_ = cei_state_e::CONNECTING; + socket_->connect(remote_, its_connect_error); + } else { + VSOMEIP_WARNING << "local_client_endpoint::connect: Error opening socket: " + << its_error.message() << " (" << std::dec << its_error.value() + << ")"; + its_connect_error = its_error; + } + } + // call connect_cbk asynchronously + try { + strand_.post( + std::bind(&client_endpoint_impl::connect_cbk, shared_from_this(), + its_connect_error)); + } catch (const std::exception &e) { + VSOMEIP_ERROR << "local_client_endpoint_impl::connect: " << e.what(); + } +} + +void local_tcp_client_endpoint_impl::receive() { + std::lock_guard its_lock(socket_mutex_); + if (socket_->is_open()) { + socket_->async_receive( + boost::asio::buffer(recv_buffer_), + strand_.wrap( + std::bind( + &local_tcp_client_endpoint_impl::receive_cbk, + std::dynamic_pointer_cast< + local_tcp_client_endpoint_impl + >(shared_from_this()), + std::placeholders::_1, + std::placeholders::_2 + ) + ) + ); + } +} + +// this overrides client_endpoint_impl::send to disable the pull method +// for local communication +bool local_tcp_client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { + std::lock_guard its_lock(mutex_); + bool ret(true); + const bool queue_size_zero_on_entry(queue_.empty()); + if (endpoint_impl::sending_blocked_ || + check_message_size(nullptr, _size) != cms_ret_e::MSG_OK || + !check_packetizer_space(_size) || + !check_queue_limit(_data, _size)) { + ret = false; + } else { +#if 0 + std::stringstream msg; + msg << "lce::send: "; + for (uint32_t i = 0; i < _size; i++) + msg << std::hex << std::setw(2) << std::setfill('0') + << (int)_data[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + train_->buffer_->insert(train_->buffer_->end(), _data, _data + _size); + queue_train(train_, queue_size_zero_on_entry); + train_->buffer_ = std::make_shared(); + } + return ret; +} + +void local_tcp_client_endpoint_impl::send_queued(std::pair &_entry) { + + static const byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 }; + static const byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 }; + std::vector bufs; + + bufs.push_back(boost::asio::buffer(its_start_tag)); + bufs.push_back(boost::asio::buffer(*_entry.first)); + bufs.push_back(boost::asio::buffer(its_end_tag)); + + { + std::lock_guard its_lock(socket_mutex_); + boost::asio::async_write( + *socket_, + bufs, + std::bind( + &client_endpoint_impl::send_cbk, + std::dynamic_pointer_cast< + local_tcp_client_endpoint_impl + >(shared_from_this()), + std::placeholders::_1, + std::placeholders::_2, + _entry.first + ) + ); + } +} + +void local_tcp_client_endpoint_impl::get_configured_times_from_endpoint( + service_t _service, method_t _method, + std::chrono::nanoseconds *_debouncing, + std::chrono::nanoseconds *_maximum_retention) const { + + (void)_service; + (void)_method; + (void)_debouncing; + (void)_maximum_retention; + VSOMEIP_ERROR << "local_client_endpoint_impl::get_configured_times_from_endpoint called."; +} + +void local_tcp_client_endpoint_impl::send_magic_cookie() { + +} + +void local_tcp_client_endpoint_impl::receive_cbk( + boost::system::error_code const &_error, std::size_t _bytes) { + + if (_error) { + if (_error == boost::asio::error::operation_aborted) { + // endpoint was stopped + return; + } else if (_error == boost::asio::error::connection_reset + || _error == boost::asio::error::eof + || _error == boost::asio::error::bad_descriptor) { + VSOMEIP_INFO << __func__ << " local_tcp_client_endpoint:" + " connection_reset/EOF/bad_descriptor"; + } else if (_error) { + VSOMEIP_ERROR << "Local endpoint received message (" + << _error.message() << ")"; + } + error_handler_t handler; + { + std::lock_guard its_lock(error_handler_mutex_); + handler = error_handler_; + } + if (handler) + handler(); + } else { + +#if 0 + std::stringstream msg; + msg << "lce<" << this << ">::recv: "; + for (std::size_t i = 0; i < recv_buffer_.size(); i++) + msg << std::setw(2) << std::setfill('0') << std::hex + << (int)recv_buffer_[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + + // We only handle a single message here. Check whether the message + // format matches what we do expect. + // TODO: Replace the magic numbers. + if (_bytes == VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE + && recv_buffer_[0] == 0x67 && recv_buffer_[1] == 0x37 + && recv_buffer_[2] == 0x6d && recv_buffer_[3] == 0x07 + && recv_buffer_[4] == byte_t(protocol::id_e::ASSIGN_CLIENT_ACK_ID) + && recv_buffer_[15] == 0x07 && recv_buffer_[16] == 0x6d + && recv_buffer_[17] == 0x37 && recv_buffer_[18] == 0x67) { + + auto its_routing_host = routing_host_.lock(); + if (its_routing_host) + its_routing_host->on_message(&recv_buffer_[4], + static_cast(recv_buffer_.size() - 8), this); + } + + receive(); + } +} + +bool local_tcp_client_endpoint_impl::get_remote_address( + boost::asio::ip::address &_address) const { + (void)_address; + return false; +} + +std::uint16_t local_tcp_client_endpoint_impl::get_remote_port() const { + return 0; +} + +void local_tcp_client_endpoint_impl::set_local_port() { + // local_port_ is set to zero in ctor of client_endpoint_impl -> do nothing +} + +void local_tcp_client_endpoint_impl::print_status() { + + std::string its_path(""); + std::size_t its_data_size(0); + std::size_t its_queue_size(0); + { + std::lock_guard its_lock(mutex_); + its_queue_size = queue_.size(); + its_data_size = queue_size_; + } + + VSOMEIP_INFO << "status lce: " << its_path << " queue: " + << its_queue_size << " data: " << its_data_size; +} + +std::string local_tcp_client_endpoint_impl::get_remote_information() const { + + boost::system::error_code ec; + return remote_.address().to_string(ec) + ":" + + std::to_string(remote_.port()); +} + + +bool local_tcp_client_endpoint_impl::check_packetizer_space(std::uint32_t _size) { + if (train_->buffer_->size() + _size < train_->buffer_->size()) { + VSOMEIP_ERROR << "Overflow in packetizer addition ~> abort sending!"; + return false; + } + if (train_->buffer_->size() + _size > max_message_size_ + && !train_->buffer_->empty()) { + queue_.push_back(std::make_pair(train_->buffer_, 0)); + queue_size_ += train_->buffer_->size(); + train_->buffer_ = std::make_shared(); + } + return true; +} + +bool local_tcp_client_endpoint_impl::is_reliable() const { + + return true; +} + +std::uint32_t local_tcp_client_endpoint_impl::get_max_allowed_reconnects() const { + + return (MAX_RECONNECTS_UNLIMITED); +} + +bool local_tcp_client_endpoint_impl::tp_segmentation_enabled( + service_t _service, method_t _method) const { + + (void)_service; + (void)_method; + return false; +} + +void local_tcp_client_endpoint_impl::max_allowed_reconnects_reached() { + + VSOMEIP_ERROR << "local_client_endpoint::max_allowed_reconnects_reached: " + << get_remote_information(); + error_handler_t handler; + { + std::lock_guard its_lock(error_handler_mutex_); + handler = error_handler_; + } + if (handler) + handler(); +} + +} // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/local_tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/local_tcp_server_endpoint_impl.cpp new file mode 100644 index 0000000..e3132fc --- /dev/null +++ b/implementation/endpoints/src/local_tcp_server_endpoint_impl.cpp @@ -0,0 +1,897 @@ +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include + +#include +#include + +#include + +#include "../include/endpoint_host.hpp" +#include "../include/local_tcp_server_endpoint_impl.hpp" +#include "../include/local_server_endpoint_impl_receive_op.hpp" +#include "../../configuration/include/configuration.hpp" +#include "../../protocol/include/assign_client_command.hpp" +#include "../../protocol/include/assign_client_ack_command.hpp" +#include "../../routing/include/routing_host.hpp" +#include "../../security/include/policy_manager_impl.hpp" +#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/utility.hpp" + +namespace vsomeip_v3 { + +local_tcp_server_endpoint_impl::local_tcp_server_endpoint_impl( + const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + const endpoint_type& _local, boost::asio::io_context &_io, + const std::shared_ptr& _configuration, + bool _is_routing_endpoint) + : local_tcp_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, + _io, + _configuration->get_max_message_size_local(), + _configuration->get_endpoint_queue_limit_local(), + _configuration), + acceptor_(_io), + buffer_shrink_threshold_(_configuration->get_buffer_shrink_threshold()), + local_port_(_local.port()), + is_routing_endpoint_(_is_routing_endpoint) { + is_supporting_magic_cookies_ = false; + + boost::system::error_code ec; + acceptor_.open(_local.protocol(), ec); + boost::asio::detail::throw_error(ec, "acceptor open"); + + acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "acceptor set_option"); + + acceptor_.bind(_local, ec); + boost::asio::detail::throw_error(ec, "acceptor bind"); + + acceptor_.listen(boost::asio::socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec, "acceptor listen"); +} + +local_tcp_server_endpoint_impl::~local_tcp_server_endpoint_impl() { +} + +bool local_tcp_server_endpoint_impl::is_local() const { + + return true; +} + +void local_tcp_server_endpoint_impl::start() { + + std::lock_guard its_lock(acceptor_mutex_); + if (!acceptor_.is_open()) { + boost::system::error_code ec; + acceptor_.open(local_.protocol(), ec); + boost::asio::detail::throw_error(ec, "acceptor open"); + acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "acceptor set_option"); + acceptor_.bind(local_, ec); + boost::asio::detail::throw_error(ec, "acceptor bind"); + acceptor_.listen(boost::asio::socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec, "acceptor listen"); + } + + if (acceptor_.is_open()) { + connection::ptr new_connection = connection::create( + std::dynamic_pointer_cast( + shared_from_this()), max_message_size_, + buffer_shrink_threshold_, + io_); + + { + std::unique_lock its_lock(new_connection->get_socket_lock()); + acceptor_.async_accept( + new_connection->get_socket(), + std::bind( + &local_tcp_server_endpoint_impl::accept_cbk, + std::dynamic_pointer_cast< + local_tcp_server_endpoint_impl + >(shared_from_this()), + new_connection, + std::placeholders::_1 + ) + ); + } + } +} + +void local_tcp_server_endpoint_impl::stop() { + + server_endpoint_impl::stop(); + { + std::lock_guard its_lock(acceptor_mutex_); + if (acceptor_.is_open()) { + boost::system::error_code its_error; + acceptor_.close(its_error); + } + } + { + std::lock_guard its_lock(connections_mutex_); + for (const auto &c : connections_) { + c.second->stop(); + } + connections_.clear(); + } +} + +bool local_tcp_server_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { +#if 0 + std::stringstream msg; + msg << "lse(" << get_local_port() << ")::send "; + for (uint32_t i = 0; i < _size; i++) + msg << std::setw(2) << std::setfill('0') << std::hex << (int)_data[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + std::lock_guard its_lock(mutex_); + if (endpoint_impl::sending_blocked_) { + return false; + } + + client_t its_client; + std::memcpy(&its_client, &_data[protocol::COMMAND_HEADER_SIZE], sizeof(its_client)); + + connection::ptr its_connection; + { + std::lock_guard its_lock(connections_mutex_); + const auto its_iterator = connections_.find(its_client); + if (its_iterator == connections_.end()) { + return false; + } else { + its_connection = its_iterator->second; + } + } + + auto its_buffer = std::make_shared(); + its_buffer->insert(its_buffer->end(), _data, _data + _size); + its_connection->send_queued(its_buffer); + + return true; +} + +bool local_tcp_server_endpoint_impl::send_to( + const std::shared_ptr _target, + const byte_t *_data, uint32_t _size) { + + (void)_target; + (void)_data; + (void)_size; + return false; +} + +bool local_tcp_server_endpoint_impl::send_error( + const std::shared_ptr _target, + const byte_t *_data, uint32_t _size) { + + (void)_target; + (void)_data; + (void)_size; + return false; +} + +bool local_tcp_server_endpoint_impl::send_queued( + const target_data_iterator_type _it) { + + (void)_it; + + return false; +} + +void local_tcp_server_endpoint_impl::receive() { + + // intentionally left empty +} + +bool local_tcp_server_endpoint_impl::get_default_target( + service_t, + local_tcp_server_endpoint_impl::endpoint_type &) const { + + return false; +} + +bool local_tcp_server_endpoint_impl::add_connection(const client_t &_client, + const std::shared_ptr &_connection) { + + bool ret = false; + std::lock_guard its_lock(connections_mutex_); + auto find_connection = connections_.find(_client); + if (find_connection == connections_.end()) { + connections_[_client] = _connection; + ret = true; + } else { + VSOMEIP_WARNING << "Attempt to add already existing " + "connection to client " << std::hex << _client; + } + return ret; +} + +void local_tcp_server_endpoint_impl::remove_connection( + const client_t &_client) { + + std::lock_guard its_lock(connections_mutex_); + connections_.erase(_client); +} + +void local_tcp_server_endpoint_impl::accept_cbk( + const connection::ptr& _connection, boost::system::error_code const &_error) { + if (_error != boost::asio::error::bad_descriptor + && _error != boost::asio::error::operation_aborted + && _error != boost::asio::error::no_descriptors) { + start(); + } else if (_error == boost::asio::error::no_descriptors) { + VSOMEIP_ERROR << "local_tcp_server_endpoint_impl::accept_cbk: " + << _error.message() << " (" << std::dec << _error.value() + << ") Will try to accept again in 1000ms"; + std::shared_ptr its_timer = + std::make_shared(io_, + std::chrono::milliseconds(1000)); + auto its_ep = std::dynamic_pointer_cast( + shared_from_this()); + its_timer->async_wait([its_timer, its_ep] + (const boost::system::error_code& _error) { + if (!_error) { + its_ep->start(); + } + }); + } + + if (!_error) { + _connection->start(); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// class local_service_impl::connection +/////////////////////////////////////////////////////////////////////////////// + +local_tcp_server_endpoint_impl::connection::connection( + const std::shared_ptr &_server, + std::uint32_t _max_message_size, + std::uint32_t _initial_recv_buffer_size, + std::uint32_t _buffer_shrink_threshold, + boost::asio::io_context &_io) + : socket_(_io), + server_(_server), + recv_buffer_size_initial_(_initial_recv_buffer_size + 8), + max_message_size_(_max_message_size), + recv_buffer_(recv_buffer_size_initial_, 0), + recv_buffer_size_(0), + missing_capacity_(0), + shrink_count_(0), + buffer_shrink_threshold_(_buffer_shrink_threshold), + bound_client_(VSOMEIP_CLIENT_UNSET), + bound_client_host_(""), + assigned_client_(false) { + if (_server->is_routing_endpoint_ && + !_server->configuration_->is_security_enabled()) { + assigned_client_ = true; + } + + sec_client_.client_type = VSOMEIP_CLIENT_TCP; + sec_client_.client.ip_client.ip = 0; + sec_client_.client.ip_client.port = 0; +} + +local_tcp_server_endpoint_impl::connection::ptr +local_tcp_server_endpoint_impl::connection::create( + const std::shared_ptr& _server, + std::uint32_t _max_message_size, + std::uint32_t _buffer_shrink_threshold, + boost::asio::io_context &_io) { + const std::uint32_t its_initial_buffer_size + = static_cast(protocol::COMMAND_HEADER_SIZE + + sizeof(instance_t) + sizeof(bool) + sizeof(bool)); + return ptr(new connection(_server, _max_message_size, its_initial_buffer_size, + _buffer_shrink_threshold, _io)); +} + +local_tcp_server_endpoint_impl::socket_type & +local_tcp_server_endpoint_impl::connection::get_socket() { + return socket_; +} + +std::unique_lock +local_tcp_server_endpoint_impl::connection::get_socket_lock() { + return std::unique_lock(socket_mutex_); +} + +void local_tcp_server_endpoint_impl::connection::start() { + std::lock_guard its_lock(socket_mutex_); + if (socket_.is_open()) { + const std::size_t its_capacity(recv_buffer_.capacity()); + if (recv_buffer_size_ > its_capacity) { + VSOMEIP_ERROR << __func__ << "Received buffer size is greater than the buffer capacity!" + << " recv_buffer_size_: " << recv_buffer_size_ + << " its_capacity: " << its_capacity; + return; + } + size_t left_buffer_size = its_capacity - recv_buffer_size_; + try { + if (missing_capacity_) { + if (missing_capacity_ > MESSAGE_SIZE_UNLIMITED) { + VSOMEIP_ERROR << "Missing receive buffer capacity exceeds allowed maximum!"; + return; + } + const std::size_t its_required_capacity(recv_buffer_size_ + missing_capacity_); + if (its_capacity < its_required_capacity) { + // Make the resize to its_required_capacity + recv_buffer_.reserve(its_required_capacity); + recv_buffer_.resize(its_required_capacity, 0x0); + } + left_buffer_size = missing_capacity_; + missing_capacity_ = 0; + } else if (buffer_shrink_threshold_ + && shrink_count_ > buffer_shrink_threshold_ + && recv_buffer_size_ == 0) { + // In this case, make the resize to recv_buffer_size_initial_ + recv_buffer_.resize(recv_buffer_size_initial_, 0x0); + recv_buffer_.shrink_to_fit(); + // And set buffer_size to recv_buffer_size_initial_, the same of our resize + left_buffer_size = recv_buffer_size_initial_; + shrink_count_ = 0; + } + } catch (const std::exception &e) { + handle_recv_buffer_exception(e); + // don't start receiving again + return; + } + +#if VSOMEIP_BOOST_VERSION < 106600 + socket_.async_receive( + boost::asio::buffer(&recv_buffer_[recv_buffer_size_], left_buffer_size), + std::bind( + &local_tcp_server_endpoint_impl::connection::receive_cbk, + shared_from_this(), + std::placeholders::_1, + std::placeholders::_2 + ) + ); +#else + socket_.async_receive( + boost::asio::buffer(&recv_buffer_[recv_buffer_size_], left_buffer_size), + std::bind( + &local_tcp_server_endpoint_impl::connection::receive_cbk, + shared_from_this(), + std::placeholders::_1, + std::placeholders::_2 + ) + ); +#endif + } +} + +void local_tcp_server_endpoint_impl::connection::stop() { + std::lock_guard its_lock(socket_mutex_); + if (socket_.is_open()) { +#if defined(__linux__) || defined(ANDROID) + if (-1 == fcntl(socket_.native_handle(), F_GETFD)) { + VSOMEIP_ERROR << "lse: socket/handle closed already '" << std::string(std::strerror(errno)) + << "' (" << errno << ") " << get_path_local(); + } +#endif + boost::system::error_code its_error; + socket_.shutdown(socket_.shutdown_both, its_error); + socket_.close(its_error); + } +} + +void local_tcp_server_endpoint_impl::connection::send_queued( + const message_buffer_ptr_t& _buffer) { + + std::shared_ptr its_server(server_.lock()); + if (!its_server) { + VSOMEIP_TRACE << "local_server_endpoint_impl::connection::send_queued " + " couldn't lock server_"; + return; + } + + static const byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 }; + static const byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 }; + std::vector bufs; + +#if 0 + std::stringstream msg; + msg << "lse::sq: "; + for (std::size_t i = 0; i < _buffer->size(); i++) + msg << std::setw(2) << std::setfill('0') << std::hex + << (int)(*_buffer)[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + + bufs.push_back(boost::asio::buffer(its_start_tag)); + bufs.push_back(boost::asio::buffer(*_buffer)); + bufs.push_back(boost::asio::buffer(its_end_tag)); + + { + std::lock_guard its_lock(socket_mutex_); + boost::asio::async_write( + socket_, + bufs, + std::bind( + &local_tcp_server_endpoint_impl::connection::send_cbk, + shared_from_this(), + _buffer, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + } +} + +client_t local_tcp_server_endpoint_impl::assign_client( + const byte_t *_data, uint32_t _size) { + + std::vector its_data(_data, _data + _size); + + protocol::assign_client_command its_command; + protocol::error_e its_error; + + its_command.deserialize(its_data, its_error); + if (its_error != protocol::error_e::ERROR_OK) { + VSOMEIP_ERROR << __func__ + << ": assign client command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + return (VSOMEIP_CLIENT_UNSET); + } + + return (utility::request_client_id(configuration_, + its_command.get_name(), its_command.get_client())); +} + +void local_tcp_server_endpoint_impl::get_configured_times_from_endpoint( + service_t _service, + method_t _method, std::chrono::nanoseconds *_debouncing, + std::chrono::nanoseconds *_maximum_retention) const { + (void)_service; + (void)_method; + (void)_debouncing; + (void)_maximum_retention; + VSOMEIP_ERROR << "local_tcp_server_endpoint_impl::get_configured_times_from_endpoint."; +} + +void local_tcp_server_endpoint_impl::connection::send_cbk(const message_buffer_ptr_t _buffer, + boost::system::error_code const &_error, std::size_t _bytes) { + (void)_buffer; + (void)_bytes; + if (_error) + VSOMEIP_WARNING << "sei::send_cbk received error: " << _error.message(); +} + +void local_tcp_server_endpoint_impl::connection::receive_cbk( + boost::system::error_code const &_error, std::size_t _bytes) +{ + std::shared_ptr its_server(server_.lock()); + if (!its_server) { + VSOMEIP_TRACE << "local_server_endpoint_impl::connection::receive_cbk " + " couldn't lock server_"; + return; + } + std::shared_ptr its_host = its_server->routing_host_.lock(); + if (!its_host) + return; + + if (_error == boost::asio::error::operation_aborted) { + if (its_server->is_routing_endpoint_ && its_server->configuration_ && + bound_client_ != VSOMEIP_CLIENT_UNSET) { + utility::release_client_id(its_server->configuration_->get_network(), + bound_client_); + set_bound_client(VSOMEIP_CLIENT_UNSET); + } + + // connection was stopped + return; + } + + bool is_error(false); + std::size_t its_start = 0; + std::size_t its_end = 0; + std::size_t its_iteration_gap = 0; + std::uint32_t its_command_size = 0; + + if (!_error && 0 < _bytes) { +#if 0 + std::stringstream msg; + msg << "lse::c<" << this << ">rcb: "; + for (std::size_t i = 0; i < _bytes + recv_buffer_size_; i++) + msg << std::setw(2) << std::setfill('0') << std::hex + << (int) (recv_buffer_[i]) << " "; + VSOMEIP_INFO << msg.str(); +#endif + + if (recv_buffer_size_ + _bytes < recv_buffer_size_) { + VSOMEIP_ERROR << "receive buffer overflow in local server endpoint ~> abort!"; + return; + } + recv_buffer_size_ += _bytes; + + bool message_is_empty(false); + bool found_message(false); + + do { + found_message = false; + message_is_empty = false; + + its_start = 0 + its_iteration_gap; + if (its_start + 3 < its_start) { + VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; + return; + } + while (its_start + 3 < recv_buffer_size_ + its_iteration_gap && + (recv_buffer_[its_start] != 0x67 || + recv_buffer_[its_start+1] != 0x37 || + recv_buffer_[its_start+2] != 0x6d || + recv_buffer_[its_start+3] != 0x07)) { + its_start++; + } + + if (its_start + 3 == recv_buffer_size_ + its_iteration_gap) { + message_is_empty = true; + } else { + its_start += 4; + } + + if (!message_is_empty) { + if (its_start + protocol::COMMAND_POSITION_SIZE + 3 < recv_buffer_size_ + its_iteration_gap) { + its_command_size = VSOMEIP_BYTES_TO_LONG( + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+3], + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+2], + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+1], + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE]); + + its_end = its_start + protocol::COMMAND_POSITION_SIZE + 3 + its_command_size; + } else { + its_end = its_start; + } + if (its_command_size && max_message_size_ != MESSAGE_SIZE_UNLIMITED + && its_command_size > max_message_size_) { + std::lock_guard its_lock(socket_mutex_); + VSOMEIP_ERROR << "Received a local message which exceeds " + << "maximum message size (" << std::dec << its_command_size + << ") aborting! local: " << get_path_local() << " remote: " + << get_path_remote(); + recv_buffer_.resize(recv_buffer_size_initial_, 0x0); + recv_buffer_.shrink_to_fit(); + return; + } + if (its_end + 3 < its_end) { + VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; + return; + } + while (its_end + 3 < recv_buffer_size_ + its_iteration_gap && + (recv_buffer_[its_end] != 0x07 || + recv_buffer_[its_end+1] != 0x6d || + recv_buffer_[its_end+2] != 0x37 || + recv_buffer_[its_end+3] != 0x67)) { + its_end ++; + } + if (its_end + 4 < its_end) { + VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; + return; + } + // check if we received a full message + if (recv_buffer_size_ + its_iteration_gap < its_end + 4 + || recv_buffer_[its_end] != 0x07 + || recv_buffer_[its_end+1] != 0x6d + || recv_buffer_[its_end+2] != 0x37 + || recv_buffer_[its_end+3] != 0x67) { + // command (1 Byte) + version (2 Byte) client id (2 Byte) + // + command size (4 Byte) + data itself + stop tag (4 byte) + // = 11 Bytes not covered in command size. + // If need to change the recv_buffer_, change the value of missing_capacity_ + // in this if/else, otherwise it is 0 + if (its_start - its_iteration_gap + its_command_size + + protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE > recv_buffer_size_) { + missing_capacity_ = + std::uint32_t(its_start) - std::uint32_t(its_iteration_gap) + + its_command_size + std::uint32_t(protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE) + - std::uint32_t(recv_buffer_size_); + } else if (recv_buffer_size_ < protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE) { + // to little data to read out the command size + // minimal amount of data needed to read out command size = 11 + missing_capacity_ = static_cast( + protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE - recv_buffer_size_); + } else { + std::stringstream local_msg; + for (std::size_t i = its_iteration_gap; + i < recv_buffer_size_ + its_iteration_gap && + i - its_iteration_gap < 32; i++) { + local_msg << std::setw(2) << std::setfill('0') + << std::hex << (int) recv_buffer_[i] << " "; + } + VSOMEIP_ERROR << "lse::c<" << this + << ">rcb: recv_buffer_size is: " << std::dec + << recv_buffer_size_ << " but couldn't read " + "out command size. recv_buffer_capacity: " + << std::dec << recv_buffer_.capacity() + << " its_iteration_gap: " << std::dec + << its_iteration_gap << " bound client: 0x" + << std::hex << bound_client_ << " buffer: " + << local_msg.str(); + recv_buffer_size_ = 0; + missing_capacity_ = 0; + its_iteration_gap = 0; + message_is_empty = true; + } + } + } + + if (!message_is_empty && + its_end + 3 < recv_buffer_size_ + its_iteration_gap) { + + if (its_server->is_routing_endpoint_ + && recv_buffer_[its_start] == protocol::id_e::ASSIGN_CLIENT_ID) { + client_t its_client = its_server->assign_client( + &recv_buffer_[its_start], uint32_t(its_end - its_start)); + { + set_bound_client(its_client); + its_host->add_known_client(its_client, get_bound_client_host()); + its_server->add_connection(its_client, shared_from_this()); + } + its_server->send_client_identifier(its_client); + assigned_client_ = true; + } else if (!its_server->is_routing_endpoint_ || assigned_client_) { + + auto its_address = socket_.remote_endpoint().address(); + auto its_port = socket_.remote_endpoint().port(); + + sec_client_.client_type = VSOMEIP_CLIENT_TCP; + if (its_address.is_v4()) { + sec_client_.client.ip_client.ip + = htonl(uint32_t(its_address.to_v4().to_ulong())); + } + sec_client_.client.ip_client.port = its_port; + + its_host->on_message(&recv_buffer_[its_start], + uint32_t(its_end - its_start), its_server.get(), + false, bound_client_, &sec_client_, + its_address, its_port); + } else { + VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() + << " didn't receive VSOMEIP_ASSIGN_CLIENT as first message"; + } + #if 0 + std::stringstream local_msg; + local_msg << "lse::c<" << this << ">rcb::thunk: "; + for (std::size_t i = its_start; i < its_end; i++) + local_msg << std::setw(2) << std::setfill('0') << std::hex + << (int) recv_buffer_[i] << " "; + VSOMEIP_INFO << local_msg.str(); + #endif + calculate_shrink_count(); + recv_buffer_size_ -= (its_end + 4 - its_iteration_gap); + missing_capacity_ = 0; + its_command_size = 0; + found_message = true; + its_iteration_gap = its_end + 4; + } else { + if (its_iteration_gap) { + // Message not complete and not in front of the buffer! + // Copy last part to front for consume in future receive_cbk call! + for (size_t i = 0; i < recv_buffer_size_; ++i) { + recv_buffer_[i] = recv_buffer_[i + its_iteration_gap]; + } + // Still more capacity needed after shifting everything to front? + if (missing_capacity_ && + missing_capacity_ <= recv_buffer_.capacity() - recv_buffer_size_) { + missing_capacity_ = 0; + } + } else if (message_is_empty) { + VSOMEIP_ERROR << "Received garbage data."; + is_error = true; + } + } + } while (recv_buffer_size_ > 0 && found_message); + } + + if (_error == boost::asio::error::eof + || _error == boost::asio::error::connection_reset + || is_error) { + stop(); + its_server->remove_connection(bound_client_); + policy_manager_impl::get()->remove_client_to_sec_client_mapping(bound_client_); + } else if (_error != boost::asio::error::bad_descriptor) { + start(); + } +} + +void local_tcp_server_endpoint_impl::connection::set_bound_client(client_t _client) { + bound_client_ = _client; +} + +client_t local_tcp_server_endpoint_impl::connection::get_bound_client() const { + return bound_client_; +} + +void local_tcp_server_endpoint_impl::connection::set_bound_client_host( + const std::string &_bound_client_host) { + bound_client_host_ = _bound_client_host; +} + +std::string local_tcp_server_endpoint_impl::connection::get_bound_client_host() const { + return bound_client_host_; +} + +void local_tcp_server_endpoint_impl::connection::calculate_shrink_count() { + if (buffer_shrink_threshold_) { + if (recv_buffer_.capacity() != recv_buffer_size_initial_) { + if (recv_buffer_size_ < (recv_buffer_.capacity() >> 1)) { + shrink_count_++; + } else { + shrink_count_ = 0; + } + } + } +} + +std::string local_tcp_server_endpoint_impl::connection::get_path_local() const { + boost::system::error_code ec; + std::string its_local_path; + if (socket_.is_open()) { + endpoint_type its_local_endpoint = socket_.local_endpoint(ec); + if (!ec) { + its_local_path += its_local_endpoint.address().to_string(ec); + its_local_path += ":"; + its_local_path += std::to_string(its_local_endpoint.port()); + } + } + return its_local_path; +} + +std::string local_tcp_server_endpoint_impl::connection::get_path_remote() const { + boost::system::error_code ec; + std::string its_remote_path; + if (socket_.is_open()) { + endpoint_type its_remote_endpoint = socket_.remote_endpoint(ec); + if (!ec) { + its_remote_path += its_remote_endpoint.address().to_string(ec); + its_remote_path += ":"; + its_remote_path += std::to_string(its_remote_endpoint.port()); + } + } + return its_remote_path; +} + +void local_tcp_server_endpoint_impl::connection::handle_recv_buffer_exception( + const std::exception &_e) { + std::stringstream its_message; + its_message <<"local_tcp_server_endpoint_impl::connection catched exception" + << _e.what() << " local: " << get_path_local() << " remote: " + << get_path_remote() << " shutting down connection. Start of buffer: "; + + for (std::size_t i = 0; i < recv_buffer_size_ && i < 16; i++) { + its_message << std::setw(2) << std::setfill('0') << std::hex + << (int) (recv_buffer_[i]) << " "; + } + + its_message << " Last 16 Bytes captured: "; + for (int i = 15; recv_buffer_size_ > 15u && i >= 0; i--) { + its_message << std::setw(2) << std::setfill('0') << std::hex + << (int) (recv_buffer_[static_cast(i)]) << " "; + } + VSOMEIP_ERROR << its_message.str(); + recv_buffer_.clear(); + if (socket_.is_open()) { + boost::system::error_code its_error; + socket_.shutdown(socket_.shutdown_both, its_error); + socket_.close(its_error); + } + std::shared_ptr its_server = server_.lock(); + if (its_server) { + its_server->remove_connection(bound_client_); + } +} + +std::size_t +local_tcp_server_endpoint_impl::connection::get_recv_buffer_capacity() const { + return recv_buffer_.capacity(); +} + +void local_tcp_server_endpoint_impl::print_status() { + std::lock_guard its_lock(mutex_); + connections_t its_connections; + { + std::lock_guard its_lock(connections_mutex_); + its_connections = connections_; + } + std::string its_local_path("TCP"); + VSOMEIP_INFO << "status lse: " << its_local_path << " connections: " + << std::dec << its_connections.size() << " queues: " + << std::dec << targets_.size(); + for (const auto &c : its_connections) { + std::string its_remote_path; // TODO: construct the path + + std::size_t its_recv_size(0); + { + std::unique_lock c_s_lock(c.second->get_socket_lock()); + its_recv_size = c.second->get_recv_buffer_capacity(); + } + + VSOMEIP_INFO << "status lse: client: " << its_remote_path + << " recv_buffer: " << std::dec << its_recv_size; + } +} +std::string local_tcp_server_endpoint_impl::get_remote_information( + const target_data_iterator_type _it) const { + boost::system::error_code ec; + return _it->first.address().to_string(ec) + ":" + + std::to_string(_it->first.port()); +} + +std::string local_tcp_server_endpoint_impl::get_remote_information( + const endpoint_type& _remote) const { + + boost::system::error_code ec; + return _remote.address().to_string(ec) + ":" + + std::to_string(_remote.port()); +} + +bool local_tcp_server_endpoint_impl::is_reliable() const { + return false; +} + +std::uint16_t local_tcp_server_endpoint_impl::get_local_port() const { + + return local_port_; +} + +void local_tcp_server_endpoint_impl::set_local_port(std::uint16_t _port) { + + (void)_port; + // Intentionally left empty +} + +bool local_tcp_server_endpoint_impl::check_packetizer_space( + target_data_iterator_type _it, message_buffer_ptr_t* _packetizer, + std::uint32_t _size) { + + if ((*_packetizer)->size() + _size < (*_packetizer)->size()) { + VSOMEIP_ERROR << "Overflow in packetizer addition ~> abort sending!"; + return false; + } + if ((*_packetizer)->size() + _size > max_message_size_ + && !(*_packetizer)->empty()) { + _it->second.queue_.push_back(std::make_pair(*_packetizer, 0)); + _it->second.queue_size_ += (*_packetizer)->size(); + *_packetizer = std::make_shared(); + } + return true; +} + +void +local_tcp_server_endpoint_impl::send_client_identifier( + const client_t &_client) { + + protocol::assign_client_ack_command its_command; + its_command.set_client(VSOMEIP_ROUTING_CLIENT); + its_command.set_assigned(_client); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error != protocol::error_e::ERROR_OK) { + + VSOMEIP_ERROR << __func__ + << ": assign client ack command serialization failed (" + << std::dec << static_cast(its_error) << ")"; + return; + } + + send(&its_buffer[0], static_cast(its_buffer.size())); +} + +bool local_tcp_server_endpoint_impl::tp_segmentation_enabled( + service_t _service, method_t _method) const { + + (void)_service; + (void)_method; + return false; +} + +} // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/local_uds_client_endpoint_impl.cpp b/implementation/endpoints/src/local_uds_client_endpoint_impl.cpp new file mode 100644 index 0000000..a69c3b8 --- /dev/null +++ b/implementation/endpoints/src/local_uds_client_endpoint_impl.cpp @@ -0,0 +1,383 @@ +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include + +#include + +#include +#include + +#include "../include/credentials.hpp" +#include "../include/endpoint_host.hpp" +#include "../include/local_uds_client_endpoint_impl.hpp" +#include "../include/local_uds_server_endpoint_impl.hpp" +#include "../../protocol/include/protocol.hpp" +#include "../../routing/include/routing_host.hpp" + +namespace vsomeip_v3 { + +local_uds_client_endpoint_impl::local_uds_client_endpoint_impl( + const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + const endpoint_type& _remote, + boost::asio::io_context &_io, + const std::shared_ptr& _configuration) + : local_uds_client_endpoint_base_impl(_endpoint_host, _routing_host, _remote, + _remote, _io, + _configuration->get_max_message_size_local(), + _configuration->get_endpoint_queue_limit_local(), + _configuration), + // Using _remote for the local(!) endpoint is ok, + // because we have no bind for local endpoints! + recv_buffer_(VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE, 0) { + + is_supporting_magic_cookies_ = false; +} + +local_uds_client_endpoint_impl::~local_uds_client_endpoint_impl() { + +} + +bool local_uds_client_endpoint_impl::is_local() const { + + return true; +} + +void local_uds_client_endpoint_impl::restart(bool _force) { + if (!_force && state_ == cei_state_e::CONNECTING) { + return; + } + state_ = cei_state_e::CONNECTING; + { + std::lock_guard its_lock(mutex_); + sending_blocked_ = false; + queue_.clear(); + queue_size_ = 0; + } + { + std::lock_guard its_lock(socket_mutex_); + shutdown_and_close_socket_unlocked(true); + } + was_not_connected_ = true; + reconnect_counter_ = 0; + start_connect_timer(); +} + +void local_uds_client_endpoint_impl::start() { + + connect(); +} + +void local_uds_client_endpoint_impl::stop() { + { + std::lock_guard its_lock(mutex_); + sending_blocked_ = true; + } + { + std::lock_guard its_lock(connect_timer_mutex_); + boost::system::error_code ec; + connect_timer_.cancel(ec); + } + connect_timeout_ = VSOMEIP_DEFAULT_CONNECT_TIMEOUT; + + bool is_open(false); + { + std::lock_guard its_lock(socket_mutex_); + is_open = socket_->is_open(); + } + if (is_open) { + bool send_queue_empty(false); + std::uint32_t times_slept(0); + + while (times_slept <= 50) { + mutex_.lock(); + send_queue_empty = (queue_.size() == 0); + mutex_.unlock(); + if (send_queue_empty) { + break; + } else { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + times_slept++; + } + } + } + shutdown_and_close_socket(false); +} + +void local_uds_client_endpoint_impl::connect() { + start_connecting_timer(); + boost::system::error_code its_connect_error; + { + std::lock_guard its_lock(socket_mutex_); + boost::system::error_code its_error; + socket_->open(remote_.protocol(), its_error); + + if (!its_error || its_error == boost::asio::error::already_open) { + socket_->set_option(boost::asio::socket_base::reuse_address(true), its_error); + if (its_error) { + VSOMEIP_WARNING << "local_client_endpoint_impl::connect: " + << "couldn't enable SO_REUSEADDR: " << its_error.message(); + } + state_ = cei_state_e::CONNECTING; + socket_->connect(remote_, its_connect_error); + + // Credentials + if (!its_connect_error) { + auto its_host = endpoint_host_.lock(); + if (its_host) { + credentials::send_credentials(socket_->native_handle(), + its_host->get_client(), its_host->get_client_host()); + } + } else { + VSOMEIP_WARNING << "local_client_endpoint::connect: Couldn't " + << "connect to: " << remote_.path() << " (" + << its_connect_error.message() << " / " << std::dec + << its_connect_error.value() << ")"; + } + } else { + VSOMEIP_WARNING << "local_client_endpoint::connect: Error opening socket: " + << its_error.message() << " (" << std::dec << its_error.value() + << ")"; + its_connect_error = its_error; + } + } + // call connect_cbk asynchronously + try { + strand_.post( + std::bind(&client_endpoint_impl::connect_cbk, shared_from_this(), + its_connect_error)); + } catch (const std::exception &e) { + VSOMEIP_ERROR << "local_client_endpoint_impl::connect: " << e.what(); + } +} + +void local_uds_client_endpoint_impl::receive() { + std::lock_guard its_lock(socket_mutex_); + if (socket_->is_open()) { + socket_->async_receive( + boost::asio::buffer(recv_buffer_), + strand_.wrap( + std::bind( + &local_uds_client_endpoint_impl::receive_cbk, + std::dynamic_pointer_cast< + local_uds_client_endpoint_impl + >(shared_from_this()), + std::placeholders::_1, + std::placeholders::_2 + ) + ) + ); + } +} + +// this overrides client_endpoint_impl::send to disable the pull method +// for local communication +bool local_uds_client_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { + std::lock_guard its_lock(mutex_); + bool ret(true); + const bool queue_size_zero_on_entry(queue_.empty()); + if (endpoint_impl::sending_blocked_ || + check_message_size(nullptr, _size) != cms_ret_e::MSG_OK || + !check_packetizer_space(_size) || + !check_queue_limit(_data, _size)) { + ret = false; + } else { +#if 0 + std::stringstream msg; + msg << "lce::send: "; + for (uint32_t i = 0; i < _size; i++) + msg << std::hex << std::setw(2) << std::setfill('0') + << (int)_data[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + train_->buffer_->insert(train_->buffer_->end(), _data, _data + _size); + queue_train(train_, queue_size_zero_on_entry); + train_->buffer_ = std::make_shared(); + } + return ret; +} + +void local_uds_client_endpoint_impl::send_queued(std::pair &_entry) { + + static const byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 }; + static const byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 }; + std::vector bufs; + + bufs.push_back(boost::asio::buffer(its_start_tag)); + bufs.push_back(boost::asio::buffer(*_entry.first)); + bufs.push_back(boost::asio::buffer(its_end_tag)); + + { + std::lock_guard its_lock(socket_mutex_); + boost::asio::async_write( + *socket_, + bufs, + std::bind( + &client_endpoint_impl::send_cbk, + std::dynamic_pointer_cast< + local_uds_client_endpoint_impl + >(shared_from_this()), + std::placeholders::_1, + std::placeholders::_2, + _entry.first + ) + ); + } +} + +void local_uds_client_endpoint_impl::get_configured_times_from_endpoint( + service_t _service, method_t _method, + std::chrono::nanoseconds *_debouncing, + std::chrono::nanoseconds *_maximum_retention) const { + + (void)_service; + (void)_method; + (void)_debouncing; + (void)_maximum_retention; + VSOMEIP_ERROR << "local_client_endpoint_impl::get_configured_times_from_endpoint called."; +} + +void local_uds_client_endpoint_impl::send_magic_cookie() { + +} + +void local_uds_client_endpoint_impl::receive_cbk( + boost::system::error_code const &_error, std::size_t _bytes) { + + if (_error) { + if (_error == boost::asio::error::operation_aborted) { + // endpoint was stopped + return; + } else if (_error == boost::asio::error::connection_reset + || _error == boost::asio::error::eof + || _error == boost::asio::error::bad_descriptor) { + VSOMEIP_INFO << __func__ << " local_uds_client_endpoint:" + " connection_reset/EOF/bad_descriptor"; + } else if (_error) { + VSOMEIP_ERROR << "Local endpoint received message (" + << _error.message() << ")"; + } + error_handler_t handler; + { + std::lock_guard its_lock(error_handler_mutex_); + handler = error_handler_; + } + if (handler) + handler(); + } else { + +#if 0 + std::stringstream msg; + msg << "lce<" << this << ">::recv: "; + for (std::size_t i = 0; i < recv_buffer_.size(); i++) + msg << std::setw(2) << std::setfill('0') << std::hex + << (int)recv_buffer_[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + + // We only handle a single message here. Check whether the message + // format matches what we do expect. + // TODO: Replace the magic numbers. + if (_bytes == VSOMEIP_LOCAL_CLIENT_ENDPOINT_RECV_BUFFER_SIZE + && recv_buffer_[0] == 0x67 && recv_buffer_[1] == 0x37 + && recv_buffer_[2] == 0x6d && recv_buffer_[3] == 0x07 + && recv_buffer_[4] == byte_t(protocol::id_e::ASSIGN_CLIENT_ACK_ID) + && recv_buffer_[15] == 0x07 && recv_buffer_[16] == 0x6d + && recv_buffer_[17] == 0x37 && recv_buffer_[18] == 0x67) { + + auto its_routing_host = routing_host_.lock(); + if (its_routing_host) + its_routing_host->on_message(&recv_buffer_[4], + static_cast(recv_buffer_.size() - 8), this); + } + + receive(); + } +} + +bool local_uds_client_endpoint_impl::get_remote_address( + boost::asio::ip::address &_address) const { + (void)_address; + return false; +} + +std::uint16_t local_uds_client_endpoint_impl::get_remote_port() const { + return 0; +} + +void local_uds_client_endpoint_impl::set_local_port() { + // local_port_ is set to zero in ctor of client_endpoint_impl -> do nothing +} + +void local_uds_client_endpoint_impl::print_status() { + + std::string its_path = remote_.path(); + std::size_t its_data_size(0); + std::size_t its_queue_size(0); + + { + std::lock_guard its_lock(mutex_); + its_queue_size = queue_.size(); + its_data_size = queue_size_; + } + + VSOMEIP_INFO << "status lce: " << its_path << " queue: " + << its_queue_size << " data: " << its_data_size; +} + +std::string local_uds_client_endpoint_impl::get_remote_information() const { + + return remote_.path(); +} + + +bool local_uds_client_endpoint_impl::check_packetizer_space(std::uint32_t _size) { + if (train_->buffer_->size() + _size < train_->buffer_->size()) { + VSOMEIP_ERROR << "Overflow in packetizer addition ~> abort sending!"; + return false; + } + if (train_->buffer_->size() + _size > max_message_size_ + && !train_->buffer_->empty()) { + queue_.push_back(std::make_pair(train_->buffer_, 0)); + queue_size_ += train_->buffer_->size(); + train_->buffer_ = std::make_shared(); + } + return true; +} + +bool local_uds_client_endpoint_impl::is_reliable() const { + + return false; +} + +std::uint32_t local_uds_client_endpoint_impl::get_max_allowed_reconnects() const { + + return 13; +} + +bool local_uds_client_endpoint_impl::tp_segmentation_enabled( + service_t _service, method_t _method) const { + + (void)_service; + (void)_method; + return false; +} + +void local_uds_client_endpoint_impl::max_allowed_reconnects_reached() { + + VSOMEIP_ERROR << "local_client_endpoint::max_allowed_reconnects_reached: " + << get_remote_information(); + error_handler_t handler; + { + std::lock_guard its_lock(error_handler_mutex_); + handler = error_handler_; + } + if (handler) + handler(); +} + +} // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/local_uds_server_endpoint_impl.cpp b/implementation/endpoints/src/local_uds_server_endpoint_impl.cpp new file mode 100644 index 0000000..8aa2139 --- /dev/null +++ b/implementation/endpoints/src/local_uds_server_endpoint_impl.cpp @@ -0,0 +1,1067 @@ +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include + +#include +#include + +#include + +#include "../include/credentials.hpp" +#include "../include/endpoint_host.hpp" +#include "../include/local_uds_server_endpoint_impl.hpp" +#include "../include/local_server_endpoint_impl_receive_op.hpp" +#include "../../configuration/include/configuration.hpp" +#include "../../protocol/include/assign_client_command.hpp" +#include "../../protocol/include/assign_client_ack_command.hpp" +#include "../../routing/include/routing_host.hpp" +#include "../../security/include/policy_manager_impl.hpp" +#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/utility.hpp" + +namespace vsomeip_v3 { + +local_uds_server_endpoint_impl::local_uds_server_endpoint_impl( + const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + const endpoint_type& _local, boost::asio::io_context &_io, + const std::shared_ptr& _configuration, + bool _is_routing_endpoint) + : local_uds_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, + _io, + _configuration->get_max_message_size_local(), + _configuration->get_endpoint_queue_limit_local(), + _configuration), + acceptor_(_io), + buffer_shrink_threshold_(_configuration->get_buffer_shrink_threshold()), + is_routing_endpoint_(_is_routing_endpoint) { + is_supporting_magic_cookies_ = false; + + boost::system::error_code ec; + acceptor_.open(_local.protocol(), ec); + if (ec) + VSOMEIP_ERROR << __func__ + << ": open failed (" << ec.message() << ")"; + + acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec); + if (ec) + VSOMEIP_ERROR << __func__ + << ": set reuse address option failed (" << ec.message() << ")"; + + acceptor_.bind(_local, ec); + if (ec) + VSOMEIP_ERROR << __func__ + << ": bind failed (" << ec.message() << ")"; + + acceptor_.listen(boost::asio::socket_base::max_connections, ec); + if (ec) + VSOMEIP_ERROR << __func__ + << ": listen failed (" << ec.message() << ")"; + + if (chmod(_local.path().c_str(), + static_cast(_configuration->get_permissions_uds())) == -1) { + VSOMEIP_ERROR << __func__ << ": chmod: " << strerror(errno); + } + credentials::activate_credentials(acceptor_.native_handle()); +} + +local_uds_server_endpoint_impl::local_uds_server_endpoint_impl( + const std::shared_ptr& _endpoint_host, + const std::shared_ptr& _routing_host, + const endpoint_type& _local, boost::asio::io_context &_io, + int native_socket, + const std::shared_ptr& _configuration, + bool _is_routing_endpoint) + : local_uds_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, _io, + _configuration->get_max_message_size_local(), + _configuration->get_endpoint_queue_limit_local(), + _configuration), + acceptor_(_io), + buffer_shrink_threshold_(configuration_->get_buffer_shrink_threshold()), + is_routing_endpoint_(_is_routing_endpoint) { + is_supporting_magic_cookies_ = false; + + boost::system::error_code ec; + acceptor_.assign(_local.protocol(), native_socket, ec); + if (ec) + VSOMEIP_ERROR << __func__ + << ": assign failed (" << ec.message() << ")"; + + if (chmod(_local.path().c_str(), + static_cast(_configuration->get_permissions_uds())) == -1) { + VSOMEIP_ERROR << __func__ << ": chmod: " << strerror(errno); + } + credentials::activate_credentials(acceptor_.native_handle()); +} + +local_uds_server_endpoint_impl::~local_uds_server_endpoint_impl() { + +} + +bool local_uds_server_endpoint_impl::is_local() const { + + return true; +} + +void local_uds_server_endpoint_impl::start() { + + std::lock_guard its_lock(acceptor_mutex_); + if (acceptor_.is_open()) { + connection::ptr new_connection = connection::create( + std::dynamic_pointer_cast( + shared_from_this()), max_message_size_, + buffer_shrink_threshold_, + io_); + + { + std::unique_lock its_lock(new_connection->get_socket_lock()); + acceptor_.async_accept( + new_connection->get_socket(), + std::bind( + &local_uds_server_endpoint_impl::accept_cbk, + std::dynamic_pointer_cast< + local_uds_server_endpoint_impl + >(shared_from_this()), + new_connection, + std::placeholders::_1 + ) + ); + } + } +} + +void local_uds_server_endpoint_impl::stop() { + + server_endpoint_impl::stop(); + { + std::lock_guard its_lock(acceptor_mutex_); + if (acceptor_.is_open()) { + boost::system::error_code its_error; + acceptor_.close(its_error); + } + } + { + std::lock_guard its_lock(connections_mutex_); + for (const auto &c : connections_) { + c.second->stop(); + } + connections_.clear(); + } +} + +bool local_uds_server_endpoint_impl::send(const uint8_t *_data, uint32_t _size) { +#if 0 + std::stringstream msg; + msg << "lse::send "; + for (uint32_t i = 0; i < _size; i++) + msg << std::setw(2) << std::setfill('0') << std::hex << (int)_data[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + std::lock_guard its_lock(mutex_); + if (endpoint_impl::sending_blocked_) { + return false; + } + + client_t its_client; + std::memcpy(&its_client, &_data[protocol::COMMAND_HEADER_SIZE], sizeof(its_client)); + + connection::ptr its_connection; + { + std::lock_guard its_lock(connections_mutex_); + const auto its_iterator = connections_.find(its_client); + if (its_iterator == connections_.end()) { + return false; + } else { + its_connection = its_iterator->second; + } + } + + auto its_buffer = std::make_shared(); + its_buffer->insert(its_buffer->end(), _data, _data + _size); + its_connection->send_queued(its_buffer); + + return true; +} + +bool local_uds_server_endpoint_impl::send_to( + const std::shared_ptr _target, + const byte_t *_data, uint32_t _size) { + + (void)_target; + (void)_data; + (void)_size; + return false; +} + +bool local_uds_server_endpoint_impl::send_error( + const std::shared_ptr _target, + const byte_t *_data, uint32_t _size) { + + (void)_target; + (void)_data; + (void)_size; + return false; +} + +bool local_uds_server_endpoint_impl::send_queued( + const target_data_iterator_type _it) { + + (void)_it; + + return false; +} + +void local_uds_server_endpoint_impl::receive() { + // intentionally left empty +} + +bool local_uds_server_endpoint_impl::get_default_target( + service_t, + local_uds_server_endpoint_impl::endpoint_type &) const { + + return false; +} + +bool local_uds_server_endpoint_impl::add_connection(const client_t &_client, + const std::shared_ptr &_connection) { + + bool ret = false; + std::lock_guard its_lock(connections_mutex_); + auto find_connection = connections_.find(_client); + if (find_connection == connections_.end()) { + connections_[_client] = _connection; + ret = true; + } else { + VSOMEIP_WARNING << "Attempt to add already existing " + "connection to client " << std::hex << _client; + } + return ret; +} + +void local_uds_server_endpoint_impl::remove_connection( + const client_t &_client) { + + std::lock_guard its_lock(connections_mutex_); + connections_.erase(_client); +} + +void local_uds_server_endpoint_impl::accept_cbk( + const connection::ptr& _connection, boost::system::error_code const &_error) { + if (_error != boost::asio::error::bad_descriptor + && _error != boost::asio::error::operation_aborted + && _error != boost::asio::error::no_descriptors) { + start(); + } else if (_error == boost::asio::error::no_descriptors) { + VSOMEIP_ERROR << "local_usd_server_endpoint_impl::accept_cbk: " + << _error.message() << " (" << std::dec << _error.value() + << ") Will try to accept again in 1000ms"; + std::shared_ptr its_timer = + std::make_shared(io_, + std::chrono::milliseconds(1000)); + auto its_ep = std::dynamic_pointer_cast( + shared_from_this()); + its_timer->async_wait([its_timer, its_ep] + (const boost::system::error_code& _error) { + if (!_error) { + its_ep->start(); + } + }); + } + + if (!_error) { + auto its_host = endpoint_host_.lock(); + client_t its_client = 0; + std::string its_client_host; + vsomeip_sec_client_t its_sec_client; + + its_sec_client.client_type = VSOMEIP_CLIENT_UDS; + its_sec_client.client.uds_client.user = ANY_UID; + its_sec_client.client.uds_client.group = ANY_GID; + + socket_type &its_socket = _connection->get_socket(); + if (auto creds = credentials::receive_credentials(its_socket.native_handle())) { + + its_client = std::get<0>(*creds); + its_client_host = std::get<3>(*creds); + + its_sec_client.client.uds_client.user = std::get<1>(*creds); + its_sec_client.client.uds_client.group = std::get<2>(*creds); + } else { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_host->get_client() + << " is rejecting new connection because client credentials couldn't be received!"; + boost::system::error_code er; + its_socket.shutdown(its_socket.shutdown_both, er); + its_socket.close(er); + return; + } + + if (its_host && configuration_->is_security_enabled()) { + if (!configuration_->check_routing_credentials(its_client, &its_sec_client)) { + VSOMEIP_WARNING << "vSomeIP Security: Rejecting new connection with routing manager client ID 0x" + << std::hex << its_client + << " uid/gid= " << std::dec + << its_sec_client.client.uds_client.user << "/" + << its_sec_client.client.uds_client.group + << " because passed credentials do not match with routing manager credentials!"; + boost::system::error_code er; + its_socket.shutdown(its_socket.shutdown_both, er); + its_socket.close(er); + return; + } + + if (is_routing_endpoint_) { + // rm_impl receives VSOMEIP_CLIENT_UNSET initially -> check later + _connection->set_bound_sec_client(its_sec_client); + _connection->set_bound_client_host(its_client_host); + } else { + { + std::lock_guard its_connection_lock(connections_mutex_); + // rm_impl receives VSOMEIP_CLIENT_UNSET initially -> check later + const auto found_client = connections_.find(its_client); + if (found_client != connections_.end()) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex + << its_host->get_client() << " is rejecting new connection with client ID 0x" + << its_client << " uid/gid= " << std::dec + << its_sec_client.client.uds_client.user << "/" + << its_sec_client.client.uds_client.group + << " because of already existing connection using same client ID"; + boost::system::error_code er; + its_socket.shutdown(its_socket.shutdown_both, er); + its_socket.close(er); + return; + } + } + + // Add to known clients (loads new config if needed) + std::shared_ptr its_routing_host = routing_host_.lock(); + its_routing_host->add_known_client(its_client, its_client_host); + + if (!policy_manager_impl::get()->check_credentials(its_client, &its_sec_client)) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex + << its_host->get_client() << " received client credentials from client 0x" + << its_client << " which violates the security policy : uid/gid=" + << std::dec << its_sec_client.client.uds_client.user << "/" + << its_sec_client.client.uds_client.group; + boost::system::error_code er; + its_socket.shutdown(its_socket.shutdown_both, er); + its_socket.close(er); + return; + } + // rm_impl receives VSOMEIP_CLIENT_UNSET initially -> set later + _connection->set_bound_client(its_client); + _connection->set_bound_client_host(its_client_host); + add_connection(its_client, _connection); + } + } else { + policy_manager_impl::get()->store_client_to_sec_client_mapping(its_client, &its_sec_client); + policy_manager_impl::get()->store_sec_client_to_client_mapping(&its_sec_client, its_client); + + if (!is_routing_endpoint_) { + std::shared_ptr its_routing_host = routing_host_.lock(); + its_routing_host->add_known_client(its_client, its_client_host); + _connection->set_bound_client(its_client); + } + _connection->set_bound_client_host(its_client_host); + } + + _connection->start(); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// class local_service_impl::connection +/////////////////////////////////////////////////////////////////////////////// + +local_uds_server_endpoint_impl::connection::connection( + const std::shared_ptr& _server, + std::uint32_t _max_message_size, + std::uint32_t _initial_recv_buffer_size, + std::uint32_t _buffer_shrink_threshold, + boost::asio::io_context &_io) + : socket_(_io), + server_(_server), + recv_buffer_size_initial_(_initial_recv_buffer_size + 8), + max_message_size_(_max_message_size), + recv_buffer_(recv_buffer_size_initial_, 0), + recv_buffer_size_(0), + missing_capacity_(0), + shrink_count_(0), + buffer_shrink_threshold_(_buffer_shrink_threshold), + bound_client_(VSOMEIP_CLIENT_UNSET), + bound_client_host_(""), + assigned_client_(false) { + if (_server->is_routing_endpoint_ && + !_server->configuration_->is_security_enabled()) { + assigned_client_ = true; + } + + sec_client_.client_type = VSOMEIP_CLIENT_UDS; + sec_client_.client.uds_client.user = ANY_UID; + sec_client_.client.uds_client.group = ANY_GID; +} + +local_uds_server_endpoint_impl::connection::ptr +local_uds_server_endpoint_impl::connection::create( + const std::shared_ptr& _server, + std::uint32_t _max_message_size, + std::uint32_t _buffer_shrink_threshold, + boost::asio::io_context &_io) { + const std::uint32_t its_initial_buffer_size + = static_cast(protocol::COMMAND_HEADER_SIZE + + sizeof(instance_t) + sizeof(bool) + sizeof(bool)); + return ptr(new connection(_server, _max_message_size, its_initial_buffer_size, + _buffer_shrink_threshold, _io)); +} + +local_uds_server_endpoint_impl::socket_type & +local_uds_server_endpoint_impl::connection::get_socket() { + return socket_; +} + +std::unique_lock +local_uds_server_endpoint_impl::connection::get_socket_lock() { + return std::unique_lock(socket_mutex_); +} + +void local_uds_server_endpoint_impl::connection::start() { + std::lock_guard its_lock(socket_mutex_); + if (socket_.is_open()) { + const std::size_t its_capacity(recv_buffer_.capacity()); + if (recv_buffer_size_ > its_capacity) { + VSOMEIP_ERROR << __func__ << "Received buffer size is greater than the buffer capacity!" + << " recv_buffer_size_: " << recv_buffer_size_ + << " its_capacity: " << its_capacity; + return; + } + size_t left_buffer_size = its_capacity - recv_buffer_size_; + try { + if (missing_capacity_) { + if (missing_capacity_ > MESSAGE_SIZE_UNLIMITED) { + VSOMEIP_ERROR << "Missing receive buffer capacity exceeds allowed maximum!"; + return; + } + const std::size_t its_required_capacity(recv_buffer_size_ + missing_capacity_); + if (its_capacity < its_required_capacity) { + // Make the resize to its_required_capacity + recv_buffer_.reserve(its_required_capacity); + recv_buffer_.resize(its_required_capacity, 0x0); + } + left_buffer_size = missing_capacity_; + missing_capacity_ = 0; + } else if (buffer_shrink_threshold_ + && shrink_count_ > buffer_shrink_threshold_ + && recv_buffer_size_ == 0) { + // In this case, make the resize to recv_buffer_size_initial_ + recv_buffer_.resize(recv_buffer_size_initial_, 0x0); + recv_buffer_.shrink_to_fit(); + // And set buffer_size to recv_buffer_size_initial_, the same of our resize + left_buffer_size = recv_buffer_size_initial_; + shrink_count_ = 0; + } + } catch (const std::exception &e) { + handle_recv_buffer_exception(e); + // don't start receiving again + return; + } + +#if VSOMEIP_BOOST_VERSION >= 106600 + local_server_endpoint_impl_receive_op its_operation { + socket_, + std::bind( + &local_uds_server_endpoint_impl::connection::receive_cbk, + shared_from_this(), + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + std::placeholders::_4 + ), + &recv_buffer_[recv_buffer_size_], + left_buffer_size, + std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::min() + }; + socket_.async_wait(socket_type::wait_read, its_operation); +#else + socket_.async_receive( + boost::asio::buffer(&recv_buffer_[recv_buffer_size_], left_buffer_size), + std::bind( + &local_uds_server_endpoint_impl::connection::receive_cbk, + shared_from_this(), + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + std::placeholders::_4 + ) + ); +#endif + } +} + +void local_uds_server_endpoint_impl::connection::stop() { + std::lock_guard its_lock(socket_mutex_); + if (socket_.is_open()) { + if (-1 == fcntl(socket_.native_handle(), F_GETFD)) { + VSOMEIP_ERROR << "lse: socket/handle closed already '" << std::string(std::strerror(errno)) + << "' (" << errno << ") " << get_path_local(); + } + boost::system::error_code its_error; + socket_.shutdown(socket_.shutdown_both, its_error); + socket_.close(its_error); + } +} + +void local_uds_server_endpoint_impl::connection::send_queued( + const message_buffer_ptr_t& _buffer) { + + std::shared_ptr its_server(server_.lock()); + if (!its_server) { + VSOMEIP_TRACE << "local_uds_server_endpoint_impl::connection::send_queued " + " couldn't lock server_"; + return; + } + + static const byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 }; + static const byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 }; + std::vector bufs; + +#if 0 + std::stringstream msg; + msg << "lse::sq: "; + for (std::size_t i = 0; i < _buffer->size(); i++) + msg << std::setw(2) << std::setfill('0') << std::hex + << (int)(*_buffer)[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + + bufs.push_back(boost::asio::buffer(its_start_tag)); + bufs.push_back(boost::asio::buffer(*_buffer)); + bufs.push_back(boost::asio::buffer(its_end_tag)); + + { + std::lock_guard its_lock(socket_mutex_); + boost::asio::async_write( + socket_, + bufs, + std::bind( + &local_uds_server_endpoint_impl::connection::send_cbk, + shared_from_this(), + _buffer, + std::placeholders::_1, + std::placeholders::_2 + ) + ); + } +} + +client_t local_uds_server_endpoint_impl::assign_client( + const byte_t *_data, uint32_t _size) { + + std::vector its_data(_data, _data + _size); + + protocol::assign_client_command its_command; + protocol::error_e its_error; + + its_command.deserialize(its_data, its_error); + if (its_error != protocol::error_e::ERROR_OK) { + VSOMEIP_ERROR << __func__ + << ": assign client command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + return (VSOMEIP_CLIENT_UNSET); + } + + return (utility::request_client_id(configuration_, + its_command.get_name(), its_command.get_client())); +} + +void local_uds_server_endpoint_impl::get_configured_times_from_endpoint( + service_t _service, + method_t _method, std::chrono::nanoseconds *_debouncing, + std::chrono::nanoseconds *_maximum_retention) const { + (void)_service; + (void)_method; + (void)_debouncing; + (void)_maximum_retention; + VSOMEIP_ERROR << "local_uds_server_endpoint_impl::get_configured_times_from_endpoint."; +} + +void local_uds_server_endpoint_impl::connection::send_cbk(const message_buffer_ptr_t _buffer, + boost::system::error_code const &_error, std::size_t _bytes) { + (void)_buffer; + (void)_bytes; + if (_error) + VSOMEIP_WARNING << "sei::send_cbk received error: " << _error.message(); +} + +void local_uds_server_endpoint_impl::connection::receive_cbk( + boost::system::error_code const &_error, std::size_t _bytes, + std::uint32_t const &_uid, std::uint32_t const &_gid) +{ + std::shared_ptr its_server(server_.lock()); + if (!its_server) { + VSOMEIP_TRACE << "local_uds_server_endpoint_impl::connection::receive_cbk " + " couldn't lock server_"; + return; + } + std::shared_ptr its_host = its_server->routing_host_.lock(); + if (!its_host) + return; + + std::shared_ptr its_config = its_server->configuration_; + if (_error == boost::asio::error::operation_aborted) { + if (its_server->is_routing_endpoint_ && + bound_client_ != VSOMEIP_CLIENT_UNSET && its_config) { + utility::release_client_id(its_config->get_network(), + bound_client_); + set_bound_client(VSOMEIP_CLIENT_UNSET); + } + + // connection was stopped + return; + } + + bool is_error(false); + std::size_t its_start = 0; + std::size_t its_end = 0; + std::size_t its_iteration_gap = 0; + std::uint32_t its_command_size = 0; + + if (!_error && 0 < _bytes) { +#if 0 + std::stringstream msg; + msg << "lse::c<" << this << ">rcb: "; + for (std::size_t i = 0; i < _bytes + recv_buffer_size_; i++) + msg << std::setw(2) << std::setfill('0') << std::hex + << (int) (recv_buffer_[i]) << " "; + VSOMEIP_INFO << msg.str(); +#endif + + if (recv_buffer_size_ + _bytes < recv_buffer_size_) { + VSOMEIP_ERROR << "receive buffer overflow in local server endpoint ~> abort!"; + return; + } + recv_buffer_size_ += _bytes; + + bool message_is_empty(false); + bool found_message(false); + + do { + found_message = false; + message_is_empty = false; + + its_start = 0 + its_iteration_gap; + if (its_start + 3 < its_start) { + VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; + return; + } + while (its_start + 3 < recv_buffer_size_ + its_iteration_gap && + (recv_buffer_[its_start] != 0x67 || + recv_buffer_[its_start+1] != 0x37 || + recv_buffer_[its_start+2] != 0x6d || + recv_buffer_[its_start+3] != 0x07)) { + its_start++; + } + + if (its_start + 3 == recv_buffer_size_ + its_iteration_gap) { + message_is_empty = true; + } else { + its_start += 4; + } + + if (!message_is_empty) { + if (its_start + protocol::COMMAND_POSITION_SIZE + 3 < recv_buffer_size_ + its_iteration_gap) { + its_command_size = VSOMEIP_BYTES_TO_LONG( + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+3], + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+2], + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE+1], + recv_buffer_[its_start + protocol::COMMAND_POSITION_SIZE]); + + its_end = its_start + protocol::COMMAND_POSITION_SIZE + 3 + its_command_size; + } else { + its_end = its_start; + } + if (its_command_size && max_message_size_ != MESSAGE_SIZE_UNLIMITED + && its_command_size > max_message_size_) { + std::lock_guard its_lock(socket_mutex_); + VSOMEIP_ERROR << "Received a local message which exceeds " + << "maximum message size (" << std::dec << its_command_size + << ") aborting! local: " << get_path_local() << " remote: " + << get_path_remote(); + recv_buffer_.resize(recv_buffer_size_initial_, 0x0); + recv_buffer_.shrink_to_fit(); + return; + } + if (its_end + 3 < its_end) { + VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; + return; + } + while (its_end + 3 < recv_buffer_size_ + its_iteration_gap && + (recv_buffer_[its_end] != 0x07 || + recv_buffer_[its_end+1] != 0x6d || + recv_buffer_[its_end+2] != 0x37 || + recv_buffer_[its_end+3] != 0x67)) { + its_end ++; + } + if (its_end + 4 < its_end) { + VSOMEIP_ERROR << "buffer overflow in local server endpoint ~> abort!"; + return; + } + // check if we received a full message + if (recv_buffer_size_ + its_iteration_gap < its_end + 4 + || recv_buffer_[its_end] != 0x07 + || recv_buffer_[its_end+1] != 0x6d + || recv_buffer_[its_end+2] != 0x37 + || recv_buffer_[its_end+3] != 0x67) { + // command (1 Byte) + version (2 Byte) + client id (2 Byte) + // + command size (4 Byte) + data itself + stop tag (4 byte) + // = 13 Bytes not covered in command size. + // If need to change the recv_buffer_, change the value of missing_capacity_ + // in this if/else, otherwise it is 0 + if (its_start - its_iteration_gap + its_command_size + + protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE > recv_buffer_size_) { + missing_capacity_ = + std::uint32_t(its_start) - std::uint32_t(its_iteration_gap) + + its_command_size + std::uint32_t(protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE) + - std::uint32_t(recv_buffer_size_); + } else if (recv_buffer_size_ < protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE) { + // to little data to read out the command size + // minimal amount of data needed to read out command size = header + tag size + missing_capacity_ = static_cast( + protocol::COMMAND_HEADER_SIZE + protocol::TAG_SIZE - recv_buffer_size_); + } else { + std::stringstream local_msg; + for (std::size_t i = its_iteration_gap; + i < recv_buffer_size_ + its_iteration_gap && + i - its_iteration_gap < 32; i++) { + local_msg << std::setw(2) << std::setfill('0') + << std::hex << (int) recv_buffer_[i] << " "; + } + VSOMEIP_ERROR << "lse::c<" << this + << ">rcb: recv_buffer_size is: " << std::dec + << recv_buffer_size_ << " but couldn't read " + "out command size. recv_buffer_capacity: " + << std::dec << recv_buffer_.capacity() + << " its_iteration_gap: " << std::dec + << its_iteration_gap << " bound client: 0x" + << std::hex << bound_client_ << " buffer: " + << local_msg.str(); + recv_buffer_size_ = 0; + missing_capacity_ = 0; + its_iteration_gap = 0; + message_is_empty = true; + } + } + } + + if (!message_is_empty && + its_end + 3 < recv_buffer_size_ + its_iteration_gap) { + + if (its_server->is_routing_endpoint_ + && recv_buffer_[its_start] == byte_t(protocol::id_e::ASSIGN_CLIENT_ID)) { + client_t its_client = its_server->assign_client( + &recv_buffer_[its_start], uint32_t(its_end - its_start)); + + if (its_config && its_config->is_security_enabled()) { + // Add to known clients (loads new config if needed) + its_host->add_known_client(its_client, get_bound_client_host()); + + if (!its_server->add_connection(its_client, shared_from_this())) { + VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() + << " is rejecting new connection with client ID 0x" << its_client + << " uid/gid= " << std::dec + << sec_client_.client.uds_client.user << "/" + << sec_client_.client.uds_client.group + << " because of already existing connection using same client ID"; + stop(); + return; + } else if (!policy_manager_impl::get()->check_credentials( + its_client, &sec_client_)) { + VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() + << " received client credentials from client 0x" << its_client + << " which violates the security policy : uid/gid=" + << std::dec << sec_client_.client.uds_client.user << "/" + << sec_client_.client.uds_client.group; + its_server->remove_connection(its_client); + utility::release_client_id(its_config->get_network(), + its_client); + stop(); + return; + } + else { + set_bound_client(its_client); + } + } else { + set_bound_client(its_client); + its_host->add_known_client(its_client, get_bound_client_host()); + its_server->add_connection(its_client, shared_from_this()); + } + its_server->send_client_identifier(its_client); + assigned_client_ = true; + } else if (!its_server->is_routing_endpoint_ || assigned_client_) { + + vsomeip_sec_client_t its_sec_client; + memset(&its_sec_client, 0, sizeof(its_sec_client)); + its_sec_client.client_type = VSOMEIP_CLIENT_UDS; + its_sec_client.client.uds_client.user = _uid; + its_sec_client.client.uds_client.group = _gid; + + its_host->on_message(&recv_buffer_[its_start], + uint32_t(its_end - its_start), its_server.get(), + false, bound_client_, &its_sec_client); + } else { + VSOMEIP_WARNING << std::hex << "Client 0x" << its_host->get_client() + << " didn't receive VSOMEIP_ASSIGN_CLIENT as first message"; + } + #if 0 + std::stringstream local_msg; + local_msg << "lse::c<" << this << ">rcb::thunk: "; + for (std::size_t i = its_start; i < its_end; i++) + local_msg << std::setw(2) << std::setfill('0') << std::hex + << (int) recv_buffer_[i] << " "; + VSOMEIP_INFO << local_msg.str(); + #endif + calculate_shrink_count(); + recv_buffer_size_ -= (its_end + 4 - its_iteration_gap); + missing_capacity_ = 0; + its_command_size = 0; + found_message = true; + its_iteration_gap = its_end + 4; + } else { + if (its_iteration_gap) { + // Message not complete and not in front of the buffer! + // Copy last part to front for consume in future receive_cbk call! + for (size_t i = 0; i < recv_buffer_size_; ++i) { + recv_buffer_[i] = recv_buffer_[i + its_iteration_gap]; + } + // Still more capacity needed after shifting everything to front? + if (missing_capacity_ && + missing_capacity_ <= recv_buffer_.capacity() - recv_buffer_size_) { + missing_capacity_ = 0; + } + } else if (message_is_empty) { + VSOMEIP_ERROR << "Received garbage data."; + is_error = true; + } + } + } while (recv_buffer_size_ > 0 && found_message); + } + + if (_error == boost::asio::error::eof + || _error == boost::asio::error::connection_reset + || is_error) { + stop(); + its_server->remove_connection(bound_client_); + policy_manager_impl::get()->remove_client_to_sec_client_mapping(bound_client_); + } else if (_error != boost::asio::error::bad_descriptor) { + start(); + } +} + +void local_uds_server_endpoint_impl::connection::set_bound_client(client_t _client) { + bound_client_ = _client; +} + +client_t local_uds_server_endpoint_impl::connection::get_bound_client() const { + return bound_client_; +} + +void local_uds_server_endpoint_impl::connection::set_bound_client_host( + const std::string &_bound_client_host) { + + bound_client_host_ = _bound_client_host; +} + +std::string local_uds_server_endpoint_impl::connection::get_bound_client_host() const { + return bound_client_host_; +} + + +void local_uds_server_endpoint_impl::connection::set_bound_sec_client( + const vsomeip_sec_client_t &_sec_client) { + + sec_client_ = _sec_client; +} + +void local_uds_server_endpoint_impl::connection::calculate_shrink_count() { + if (buffer_shrink_threshold_) { + if (recv_buffer_.capacity() != recv_buffer_size_initial_) { + if (recv_buffer_size_ < (recv_buffer_.capacity() >> 1)) { + shrink_count_++; + } else { + shrink_count_ = 0; + } + } + } +} + +std::string local_uds_server_endpoint_impl::connection::get_path_local() const { + boost::system::error_code ec; + std::string its_local_path; + if (socket_.is_open()) { + endpoint_type its_local_endpoint = socket_.local_endpoint(ec); + if (!ec) { + its_local_path += its_local_endpoint.path(); + } + } + return its_local_path; +} + +std::string local_uds_server_endpoint_impl::connection::get_path_remote() const { + boost::system::error_code ec; + std::string its_remote_path; + if (socket_.is_open()) { + endpoint_type its_remote_endpoint = socket_.remote_endpoint(ec); + if (!ec) { + its_remote_path += its_remote_endpoint.path(); + } + } + return its_remote_path; +} + +void local_uds_server_endpoint_impl::connection::handle_recv_buffer_exception( + const std::exception &_e) { + std::stringstream its_message; + its_message <<"local_uds_server_endpoint_impl::connection catched exception" + << _e.what() << " local: " << get_path_local() << " remote: " + << get_path_remote() << " shutting down connection. Start of buffer: "; + + for (std::size_t i = 0; i < recv_buffer_size_ && i < 16; i++) { + its_message << std::setw(2) << std::setfill('0') << std::hex + << (int) (recv_buffer_[i]) << " "; + } + + its_message << " Last 16 Bytes captured: "; + for (int i = 15; recv_buffer_size_ > 15u && i >= 0; i--) { + its_message << std::setw(2) << std::setfill('0') << std::hex + << (int) (recv_buffer_[static_cast(i)]) << " "; + } + VSOMEIP_ERROR << its_message.str(); + recv_buffer_.clear(); + if (socket_.is_open()) { + if (-1 == fcntl(socket_.native_handle(), F_GETFD)) { + VSOMEIP_ERROR << "lse: socket/handle closed already '" << std::string(std::strerror(errno)) + << "' (" << errno << ") " << get_path_local(); + } + boost::system::error_code its_error; + socket_.shutdown(socket_.shutdown_both, its_error); + socket_.close(its_error); + } + std::shared_ptr its_server = server_.lock(); + if (its_server) { + its_server->remove_connection(bound_client_); + } +} + +std::size_t +local_uds_server_endpoint_impl::connection::get_recv_buffer_capacity() const { + return recv_buffer_.capacity(); +} + +void local_uds_server_endpoint_impl::print_status() { + std::lock_guard its_lock(mutex_); + connections_t its_connections; + { + std::lock_guard its_lock(connections_mutex_); + its_connections = connections_; + } + + std::string its_local_path(local_.path()); + + VSOMEIP_INFO << "status lse: " << its_local_path << " connections: " + << std::dec << its_connections.size() << " targets: " + << std::dec << targets_.size(); + for (const auto &c : its_connections) { + std::string its_remote_path; // TODO: construct the path + + std::size_t its_recv_size(0); + { + std::unique_lock c_s_lock(c.second->get_socket_lock()); + its_recv_size = c.second->get_recv_buffer_capacity(); + } + + VSOMEIP_INFO << "status lse: client: " << its_remote_path + << " recv_buffer: " << std::dec << its_recv_size; + } +} +std::string local_uds_server_endpoint_impl::get_remote_information( + const target_data_iterator_type _it) const { + + (void)_it; + return "local"; +} + +std::string local_uds_server_endpoint_impl::get_remote_information( + const endpoint_type& _remote) const { + + (void)_remote; + return "local"; +} + +bool local_uds_server_endpoint_impl::is_reliable() const { + return false; +} + +std::uint16_t local_uds_server_endpoint_impl::get_local_port() const { + + return 0; +} + +void local_uds_server_endpoint_impl::set_local_port(std::uint16_t _port) { + + (void)_port; + // Intentionally left empty +} + +bool local_uds_server_endpoint_impl::check_packetizer_space( + target_data_iterator_type _it, message_buffer_ptr_t* _packetizer, + std::uint32_t _size) { + + if ((*_packetizer)->size() + _size < (*_packetizer)->size()) { + VSOMEIP_ERROR << "Overflow in packetizer addition ~> abort sending!"; + return false; + } + if ((*_packetizer)->size() + _size > max_message_size_ + && !(*_packetizer)->empty()) { + _it->second.queue_.push_back(std::make_pair(*_packetizer, 0)); + _it->second.queue_size_ += (*_packetizer)->size(); + *_packetizer = std::make_shared(); + } + return true; +} + +void +local_uds_server_endpoint_impl::send_client_identifier( + const client_t &_client) { + + protocol::assign_client_ack_command its_command; + its_command.set_client(VSOMEIP_ROUTING_CLIENT); + its_command.set_assigned(_client); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error != protocol::error_e::ERROR_OK) { + + VSOMEIP_ERROR << __func__ + << ": assign client ack command serialization failed (" + << std::dec << static_cast(its_error) << ")"; + return; + } + + send(&its_buffer[0], static_cast(its_buffer.size())); +} + +bool local_uds_server_endpoint_impl::tp_segmentation_enabled( + service_t _service, method_t _method) const { + + (void)_service; + (void)_method; + return false; +} + +} // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/netlink_connector.cpp b/implementation/endpoints/src/netlink_connector.cpp index ebd432d..be5a103 100644 --- a/implementation/endpoints/src/netlink_connector.cpp +++ b/implementation/endpoints/src/netlink_connector.cpp @@ -1,9 +1,9 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include @@ -17,12 +17,6 @@ namespace vsomeip_v3 { -namespace { - const std::uint32_t ifa_request_sequence = 1; - const std::uint32_t ifi_request_sequence = 2; - const std::uint32_t rt_request_sequence = 3; -} - void netlink_connector::register_net_if_changes_handler(const net_if_changed_handler_t& _handler) { handler_ = _handler; } @@ -66,15 +60,14 @@ void netlink_connector::start() { RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_IPV4_MROUTE | RTMGRP_IPV6_MROUTE), ec); - if (ec) { + if (ec && ec != boost::asio::error::address_in_use) { VSOMEIP_WARNING << "Error binding NETLINK socket: " << ec.message(); if (handler_) { handler_(true, "n/a", true); handler_(false, "n/a", true); } -#ifndef VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS + return; -#endif // VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS } send_ifa_request(); @@ -122,7 +115,7 @@ void netlink_connector::receive_cbk(boost::system::error_code const &_error, auto its_if = net_if_flags_.find(static_cast(ifa->ifa_index)); if (its_if != net_if_flags_.end()) { if ((its_if->second & IFF_UP) && - (its_if->second & IFF_RUNNING)) { + (is_requiring_link_ ? (its_if->second & IFF_RUNNING) : true)) { if (handler_) { if_indextoname(ifa->ifa_index,ifname); handler_(true, ifname, true); @@ -148,7 +141,7 @@ void netlink_connector::receive_cbk(boost::system::error_code const &_error, net_if_flags_[ifi->ifi_index] = ifi->ifi_flags; if (net_if_index_for_address_ == ifi->ifi_index) { if ((ifi->ifi_flags & IFF_UP) && - (ifi->ifi_flags & IFF_RUNNING)) { + (is_requiring_link_ ? (ifi->ifi_flags & IFF_RUNNING) : true)) { if (handler_) { if_indextoname(static_cast(ifi->ifi_index),ifname); handler_(true, ifname, true); @@ -187,32 +180,9 @@ void netlink_connector::receive_cbk(boost::system::error_code const &_error, } case NLMSG_ERROR: { struct nlmsgerr *errmsg = (nlmsgerr *)NLMSG_DATA(nlh); - if (errmsg->error == 0) { - // Ack from netlink - break; - } - VSOMEIP_ERROR << "netlink_connector::receive_cbk received " - "error message: " << strerror(errmsg->error) - << " type " << std::dec << errmsg->msg.nlmsg_type + "error message: " << std::dec << nlh->nlmsg_type << " seq " << errmsg->msg.nlmsg_seq; - - std::string request_type{}; - if (errmsg->msg.nlmsg_type == RTM_GETADDR && errmsg->msg.nlmsg_seq == ifa_request_sequence) { - request_type = "address request"; - send_ifa_request(); - } else if (errmsg->msg.nlmsg_type == RTM_GETLINK && errmsg->msg.nlmsg_seq == ifi_request_sequence) { - request_type = "link request"; - send_ifi_request(); - } else if (errmsg->msg.nlmsg_type == RTM_GETROUTE && errmsg->msg.nlmsg_seq == rt_request_sequence) { - request_type = "route request"; - send_rt_request(); - } - - if (!request_type.empty()) { - VSOMEIP_INFO << "Retrying netlink " << request_type; - } - break; } case NLMSG_DONE: @@ -271,16 +241,16 @@ void netlink_connector::send_cbk(boost::system::error_code const &_error, std::s } void netlink_connector::send_ifa_request() { - typedef struct { + struct netlink_address_msg { struct nlmsghdr nlhdr; struct ifaddrmsg addrmsg; - } netlink_address_msg; + }; netlink_address_msg get_address_msg; memset(&get_address_msg, 0, sizeof(get_address_msg)); get_address_msg.nlhdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); get_address_msg.nlhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT; get_address_msg.nlhdr.nlmsg_type = RTM_GETADDR; - get_address_msg.nlhdr.nlmsg_seq = ifa_request_sequence; + get_address_msg.nlhdr.nlmsg_seq = 1; if (address_.is_v4()) { get_address_msg.addrmsg.ifa_family = AF_INET; } else { @@ -299,17 +269,17 @@ void netlink_connector::send_ifa_request() { } void netlink_connector::send_ifi_request() { - typedef struct { + struct netlink_link_msg { struct nlmsghdr nlhdr; struct ifinfomsg infomsg; - } netlink_link_msg; + }; netlink_link_msg get_link_msg; memset(&get_link_msg, 0, sizeof(get_link_msg)); get_link_msg.nlhdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); get_link_msg.nlhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT; get_link_msg.nlhdr.nlmsg_type = RTM_GETLINK; get_link_msg.infomsg.ifi_family = AF_UNSPEC; - get_link_msg.nlhdr.nlmsg_seq = ifi_request_sequence; + get_link_msg.nlhdr.nlmsg_seq = 2; { std::lock_guard its_lock(socket_mutex_); @@ -326,17 +296,17 @@ void netlink_connector::send_ifi_request() { } void netlink_connector::send_rt_request() { - typedef struct { + struct netlink_route_msg { struct nlmsghdr nlhdr; struct rtgenmsg routemsg; - } netlink_route_msg; + }; netlink_route_msg get_route_msg; memset(&get_route_msg, 0, sizeof(get_route_msg)); get_route_msg.nlhdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg)); get_route_msg.nlhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; get_route_msg.nlhdr.nlmsg_type = RTM_GETROUTE; - get_route_msg.nlhdr.nlmsg_seq = rt_request_sequence; + get_route_msg.nlhdr.nlmsg_seq = 3; if (multicast_address_.is_v6()) { get_route_msg.routemsg.rtgen_family = AF_INET6; } else { @@ -470,5 +440,4 @@ bool netlink_connector::check_sd_multicast_route_match(struct rtmsg* _routemsg, } // namespace vsomeip_v3 -#endif // #ifndef _WIN32 - +#endif // __linux__ or ANDROID diff --git a/implementation/endpoints/src/server_endpoint_impl.cpp b/implementation/endpoints/src/server_endpoint_impl.cpp index ddf6b25..0d06537 100644 --- a/implementation/endpoints/src/server_endpoint_impl.cpp +++ b/implementation/endpoints/src/server_endpoint_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,8 +11,13 @@ #include #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 #include +#include +#else +#include +#include +#endif #include #include @@ -30,69 +35,73 @@ template server_endpoint_impl::server_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, endpoint_type _local, - boost::asio::io_service &_io, std::uint32_t _max_message_size, + boost::asio::io_context &_io, std::uint32_t _max_message_size, configuration::endpoint_queue_limit_t _queue_limit, const std::shared_ptr& _configuration) : endpoint_impl(_endpoint_host, _routing_host, _local, _io, _max_message_size, _queue_limit, _configuration), sent_timer_(_io) { + is_sending_ = false; } template server_endpoint_impl::~server_endpoint_impl() { + } template void server_endpoint_impl::prepare_stop( - endpoint::prepare_stop_handler_t _handler, service_t _service) { + const endpoint::prepare_stop_handler_t &_handler, service_t _service) { + std::lock_guard its_lock(mutex_); bool queued_train(false); + std::vector its_erased; + boost::system::error_code ec; + if (_service == ANY_SERVICE) { // endpoint is shutting down completely endpoint_impl::sending_blocked_ = true; - boost::system::error_code ec; - for (auto const& train_iter : trains_) { - train_iter.second->departure_timer_->cancel(ec); - if (train_iter.second->buffer_->size() > 0) { - auto target_queue_iter = queues_.find(train_iter.first); - if (target_queue_iter != queues_.end()) { - auto& its_qpair = target_queue_iter->second; - const bool queue_size_zero_on_entry(its_qpair.second.empty()); - queue_train(target_queue_iter, train_iter.second, - queue_size_zero_on_entry); - queued_train = true; - } + for (auto t = targets_.begin(); t != targets_.end(); t++) { + auto its_train (t->second.train_); + // cancel dispatch timer + t->second.dispatch_timer_->cancel(ec); + if (its_train->buffer_->size() > 0) { + const bool queue_size_zero_on_entry(t->second.queue_.empty()); + if (queue_train(t, its_train, queue_size_zero_on_entry)) + its_erased.push_back(t); + queued_train = true; } } } else { - for (auto const& train_iter : trains_) { - for (auto const& passenger_iter : train_iter.second->passengers_) { + for (auto t = targets_.begin(); t != targets_.end(); t++) { + auto its_train(t->second.train_); + for (auto const& passenger_iter : its_train->passengers_) { if (passenger_iter.first == _service) { - // cancel departure timer - boost::system::error_code ec; - train_iter.second->departure_timer_->cancel(ec); + // cancel dispatch timer + t->second.dispatch_timer_->cancel(ec); // queue train - auto target_queue_iter = queues_.find(train_iter.first); - if (target_queue_iter != queues_.end()) { - const auto& its_qpair = target_queue_iter->second; - const bool queue_size_zero_on_entry(its_qpair.second.empty()); - queue_train(target_queue_iter, train_iter.second, - queue_size_zero_on_entry); - queued_train = true; - } + const bool queue_size_zero_on_entry(t->second.queue_.empty()); + // TODO: Queue all(!) trains here... + if (queue_train(t, its_train, queue_size_zero_on_entry)) + its_erased.push_back(t); + queued_train = true; break; } } } } + + for (const auto t : its_erased) + targets_.erase(t); + if (!queued_train) { if (_service == ANY_SERVICE) { - if (std::all_of(queues_.begin(), queues_.end(), - [&](const typename queue_type::value_type& q) - { return q.second.second.empty(); })) { + if (std::all_of(targets_.begin(), targets_.end(), + [&](const typename target_data_type::value_type &_t) + { return _t.second.queue_.empty(); })) { // nothing was queued and all queues are empty -> ensure cbk is called auto ptr = this->shared_from_this(); - endpoint_impl::service_.post([ptr, _handler, _service](){ + endpoint_impl::io_.post([ptr, _handler, _service](){ _handler(ptr, _service); }); } else { @@ -101,11 +110,11 @@ void server_endpoint_impl::prepare_stop( } else { // check if any of the queues contains a message of to be stopped service bool found_service_msg(false); - for (const auto& q : queues_) { - for (const auto& msg : q.second.second ) { + for (const auto &t : targets_) { + for (const auto &q : t.second.queue_) { const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*msg)[VSOMEIP_SERVICE_POS_MIN], - (*msg)[VSOMEIP_SERVICE_POS_MAX]); + (*q.first)[VSOMEIP_SERVICE_POS_MIN], + (*q.first)[VSOMEIP_SERVICE_POS_MAX]); if (its_service == _service) { found_service_msg = true; break; @@ -119,7 +128,7 @@ void server_endpoint_impl::prepare_stop( prepare_stop_handlers_[_service] = _handler; } else { // no messages of the to be stopped service are or have been queued auto ptr = this->shared_from_this(); - endpoint_impl::service_.post([ptr, _handler, _service](){ + endpoint_impl::io_.post([ptr, _handler, _service](){ _handler(ptr, _service); }); } @@ -170,7 +179,7 @@ templatebool server_endpoint_impl::send(const uint8 std::stringstream msg; msg << "sei::send "; for (uint32_t i = 0; i < _size; i++) - msg << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; + msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; VSOMEIP_INFO << msg.str(); #endif endpoint_type its_target; @@ -185,45 +194,38 @@ templatebool server_endpoint_impl::send(const uint8 const service_t its_service = VSOMEIP_BYTES_TO_WORD( _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); const client_t its_client = VSOMEIP_BYTES_TO_WORD( _data[VSOMEIP_CLIENT_POS_MIN], _data[VSOMEIP_CLIENT_POS_MAX]); const session_t its_session = VSOMEIP_BYTES_TO_WORD( _data[VSOMEIP_SESSION_POS_MIN], _data[VSOMEIP_SESSION_POS_MAX]); - requests_mutex_.lock(); - auto found_client = requests_.find(its_client); - if (found_client != requests_.end()) { - auto its_request = std::make_tuple(its_service, its_method, its_session); - auto found_request = found_client->second.find(its_request); - if (found_request != found_client->second.end()) { - its_target = found_request->second; + clients_mutex_.lock(); + auto found_client = clients_.find(its_client); + if (found_client != clients_.end()) { + auto found_session = found_client->second.find(its_session); + if (found_session != found_client->second.end()) { + its_target = found_session->second; is_valid_target = true; - found_client->second.erase(found_request); + found_client->second.erase(its_session); } else { - VSOMEIP_WARNING << "server_endpoint::send: request [" - << std::hex << std::setw(4) << std::setfill('0') - << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') - << its_method << "/" - << std::hex << std::setw(4) << std::setfill('0') - << its_client << "." - << std::hex << std::setw(4) << std::setfill('0') - << its_session - << "] could not be found."; + VSOMEIP_WARNING << "server_endpoint::send: session_id 0x" + << std::hex << its_session + << " not found for client 0x" << its_client; + const method_t its_method = + VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN], + _data[VSOMEIP_METHOD_POS_MAX]); if (its_service == VSOMEIP_SD_SERVICE && its_method == VSOMEIP_SD_METHOD) { VSOMEIP_ERROR << "Clearing clients map as a request was " "received on SD port"; - requests_.clear(); + clients_.clear(); is_valid_target = get_default_target(its_service, its_target); } } } else { is_valid_target = get_default_target(its_service, its_target); } - requests_mutex_.unlock(); + clients_mutex_.unlock(); if (is_valid_target) { is_valid_target = send_intern(its_target, _data, _size); @@ -276,9 +278,11 @@ bool server_endpoint_impl::send_intern( } } - const queue_iterator_type target_queue_iterator = find_or_create_queue_unlocked(_target); + const auto its_target_iterator = find_or_create_target_unlocked(_target); + auto &its_data(its_target_iterator->second); bool must_depart(false); + auto its_now(std::chrono::steady_clock::now()); #if 0 std::stringstream msg; @@ -287,15 +291,12 @@ bool server_endpoint_impl::send_intern( msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; VSOMEIP_DEBUG << msg.str(); #endif - // STEP 1: determine the correct train - std::shared_ptr target_train = find_or_create_train_unlocked(_target); - - const bool queue_size_zero_on_entry(target_queue_iterator->second.second.empty()); - if (!check_queue_limit(_data, _size, target_queue_iterator->second.first)) { + // STEP 1: Check queue limit + if (!check_queue_limit(_data, _size, its_data.queue_size_)) { return false; } - // STEP 2: Determine elapsed time and update the departure time and cancel the timer - target_train->update_departure_time_and_stop_departure(); + // STEP 2: Cancel the dispatch timer + cancel_dispatch_timer(its_target_iterator); // STEP 3: Get configured timings const service_t its_service = VSOMEIP_BYTES_TO_WORD( @@ -310,38 +311,38 @@ bool server_endpoint_impl::send_intern( } // STEP 4: Check if the passenger enters an empty train - const std::pair its_identifier = std::make_pair( - its_service, its_method); - if (target_train->passengers_.empty()) { - target_train->departure_ = its_retention; + const std::pair its_identifier + = std::make_pair(its_service, its_method); + if (its_data.train_->passengers_.empty()) { + its_data.train_->departure_ = its_now + its_retention; } else { - if (target_train->passengers_.end() - != target_train->passengers_.find(its_identifier)) { + if (its_data.train_->passengers_.end() + != its_data.train_->passengers_.find(its_identifier)) { must_depart = true; } else { // STEP 5: Check whether the current message fits into the current train - if (target_train->buffer_->size() + _size > endpoint_impl::max_message_size_) { + if (its_data.train_->buffer_->size() + _size > endpoint_impl::max_message_size_) { must_depart = true; } else { // STEP 6: Check debouncing time - if (its_debouncing > target_train->minimal_max_retention_time_) { + if (its_debouncing > its_data.train_->minimal_max_retention_time_) { // train's latest departure would already undershot new // passenger's debounce time must_depart = true; } else { - if (its_debouncing > target_train->departure_) { + if (its_now + its_debouncing > its_data.train_->departure_) { // train departs earlier as the new passenger's debounce // time allows must_depart = true; } else { // STEP 7: Check maximum retention time - if (its_retention < target_train->minimal_debounce_time_) { + if (its_retention < its_data.train_->minimal_debounce_time_) { // train's earliest departure would already exceed // the new passenger's retention time. must_depart = true; } else { - if (its_retention < target_train->departure_) { - target_train->departure_ = its_retention; + if (its_now + its_retention < its_data.train_->departure_) { + its_data.train_->departure_ = its_now + its_retention; } } } @@ -354,52 +355,42 @@ bool server_endpoint_impl::send_intern( if (must_depart) { // STEP 8.1: check if debounce time would be undershot here if the train // departs. Block sending until train is allowed to depart. - wait_until_debounce_time_reached(target_train); - queue_train(target_queue_iterator, target_train, - queue_size_zero_on_entry); - target_train->departure_ = its_retention; + schedule_train(its_data); + + its_data.train_ = std::make_shared(); + its_data.train_->departure_ = its_now + its_retention; } // STEP 9: insert current message buffer - target_train->buffer_->insert(target_train->buffer_->end(), _data, _data + _size); - target_train->passengers_.insert(its_identifier); + its_data.train_->buffer_->insert(its_data.train_->buffer_->end(), _data, _data + _size); + its_data.train_->passengers_.insert(its_identifier); // STEP 9.1: update the trains minimal debounce time if necessary - if (its_debouncing < target_train->minimal_debounce_time_) { - target_train->minimal_debounce_time_ = its_debouncing; + if (its_debouncing < its_data.train_->minimal_debounce_time_) { + its_data.train_->minimal_debounce_time_ = its_debouncing; } // STEP 9.2: update the trains minimal maximum retention time if necessary - if (its_retention < target_train->minimal_max_retention_time_) { - target_train->minimal_max_retention_time_ = its_retention; + if (its_retention < its_data.train_->minimal_max_retention_time_) { + its_data.train_->minimal_max_retention_time_ = its_retention; } // STEP 10: restart timer with current departure time -#ifndef _WIN32 - target_train->departure_timer_->expires_from_now(target_train->departure_); -#else - target_train->departure_timer_->expires_from_now( - std::chrono::duration_cast< - std::chrono::steady_clock::duration>(target_train->departure_)); -#endif - target_train->departure_timer_->async_wait( - std::bind(&server_endpoint_impl::flush_cbk, - this->shared_from_this(), _target, - target_train, std::placeholders::_1)); + start_dispatch_timer(its_target_iterator, its_now); return (true); } template void server_endpoint_impl::send_segments( - const tp::tp_split_messages_t &_segments, const endpoint_type &_target) { + const tp::tp_split_messages_t &_segments, std::uint32_t _separation_time, + const endpoint_type &_target) { if (_segments.size() == 0) return; - const queue_iterator_type target_queue_iterator = find_or_create_queue_unlocked(_target); - const bool queue_size_zero_on_entry(target_queue_iterator->second.second.empty()); + const auto its_target_iterator = find_or_create_target_unlocked(_target); + auto &its_data = its_target_iterator->second; - std::shared_ptr target_train = find_or_create_train_unlocked(_target); - target_train->update_departure_time_and_stop_departure(); + auto its_now(std::chrono::steady_clock::now()); const service_t its_service = VSOMEIP_BYTES_TO_WORD( (*(_segments[0]))[VSOMEIP_SERVICE_POS_MIN], (*(_segments[0]))[VSOMEIP_SERVICE_POS_MAX]); @@ -412,47 +403,63 @@ void server_endpoint_impl::send_segments( &its_debouncing, &its_retention); } // update the trains minimal debounce time if necessary - if (its_debouncing < target_train->minimal_debounce_time_) { - target_train->minimal_debounce_time_ = its_debouncing; + if (its_debouncing < its_data.train_->minimal_debounce_time_) { + its_data.train_->minimal_debounce_time_ = its_debouncing; } // update the trains minimal maximum retention time if necessary - if (its_retention < target_train->minimal_max_retention_time_) { - target_train->minimal_max_retention_time_ = its_retention; + if (its_retention < its_data.train_->minimal_max_retention_time_) { + its_data.train_->minimal_max_retention_time_ = its_retention; } // We only need to respect the debouncing. There is no need to wait for further // messages as we will send several now anyway. - if (!target_train->passengers_.empty()) { - wait_until_debounce_time_reached(target_train); - queue_train(target_queue_iterator, target_train, queue_size_zero_on_entry); + if (!its_data.train_->passengers_.empty()) { + schedule_train(its_data); + its_data.train_->departure_ = its_now + its_retention; } - const bool queue_size_still_zero(target_queue_iterator->second.second.empty()); + const bool queue_size_still_zero(its_data.queue_.empty()); for (const auto &s : _segments) { - target_queue_iterator->second.second.emplace_back(s); - target_queue_iterator->second.first += s->size(); + its_data.queue_.emplace_back(std::make_pair(s, _separation_time)); + its_data.queue_size_ += s->size(); } - if (queue_size_still_zero && !target_queue_iterator->second.second.empty()) { // no writing in progress + + if (queue_size_still_zero && !its_data.queue_.empty()) { // no writing in progress // respect minimal debounce time - wait_until_debounce_time_reached(target_train); + schedule_train(its_data); // ignore retention time and send immediately as the train is full anyway - send_queued(target_queue_iterator); + (void)send_queued(its_target_iterator); } - target_train->last_departure_ = std::chrono::steady_clock::now(); } template -void server_endpoint_impl::wait_until_debounce_time_reached( - const std::shared_ptr& _train) const { - const std::chrono::nanoseconds time_since_last_departure = - std::chrono::duration_cast( - std::chrono::steady_clock::now() - _train->last_departure_); - - if (time_since_last_departure < _train->minimal_debounce_time_) { - std::this_thread::sleep_for( - _train->minimal_debounce_time_ - time_since_last_departure); +typename server_endpoint_impl::target_data_iterator_type +server_endpoint_impl::find_or_create_target_unlocked(endpoint_type _target) { + + auto its_iterator = targets_.find(_target); + if (its_iterator == targets_.end()) { + + auto its_result = targets_.emplace( + std::make_pair(_target, endpoint_data_type(this->io_))); + its_iterator = its_result.first; } + + return (its_iterator); } +template +void server_endpoint_impl::schedule_train(endpoint_data_type &_data) { + + if (_data.has_last_departure_) { + if (_data.last_departure_ + _data.train_->minimal_debounce_time_ + > _data.train_->departure_) { + _data.train_->departure_ = _data.last_departure_ + + _data.train_->minimal_debounce_time_; + } + } + + _data.dispatched_trains_[_data.train_->departure_] + .push_back(_data.train_); +} template typename endpoint_impl::cms_ret_e server_endpoint_impl::check_message_size( @@ -469,11 +476,21 @@ typename endpoint_impl::cms_ret_e server_endpoint_impl::chec _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); if (tp_segmentation_enabled(its_service, its_method)) { - send_segments(tp::tp::tp_split_message(_data, _size), _target); - return endpoint_impl::cms_ret_e::MSG_WAS_SPLIT; + instance_t its_instance = this->get_instance(its_service); + if (its_instance != 0xFFFF) { + std::uint16_t its_max_segment_length; + std::uint32_t its_separation_time; + + this->configuration_->get_tp_configuration( + its_service, its_instance, its_method, false, + its_max_segment_length, its_separation_time); + send_segments(tp::tp::tp_split_message(_data, _size, + its_max_segment_length), its_separation_time, _target); + return endpoint_impl::cms_ret_e::MSG_WAS_SPLIT; + } } } - VSOMEIP_ERROR << "sei::send_intern: Dropping too big message (" << _size + VSOMEIP_ERROR << "sei::send_intern: Dropping to big message (" << _size << " Bytes). Maximum allowed message size is: " << endpoint_impl::max_message_size_ << " Bytes."; ret = endpoint_impl::cms_ret_e::MSG_TOO_BIG; @@ -523,72 +540,67 @@ bool server_endpoint_impl::check_queue_limit(const uint8_t *_data, std } template -void server_endpoint_impl::queue_train( - const queue_iterator_type _queue_iterator, - const std::shared_ptr& _train, - bool _queue_size_zero_on_entry) { - _queue_iterator->second.second.emplace_back(_train->buffer_); - _queue_iterator->second.first += _train->buffer_->size(); - _train->last_departure_ = std::chrono::steady_clock::now(); - _train->passengers_.clear(); - _train->buffer_ = std::make_shared(); - _train->minimal_debounce_time_ = std::chrono::nanoseconds::max(); - _train->minimal_max_retention_time_ = std::chrono::nanoseconds::max(); - if (_queue_size_zero_on_entry && !_queue_iterator->second.second.empty()) { // no writing in progress - send_queued(_queue_iterator); - } -} +bool server_endpoint_impl::queue_train( + target_data_iterator_type _it, const std::shared_ptr &_train, + bool _queue_size_zero_on_entry) { -template -typename server_endpoint_impl::queue_iterator_type -server_endpoint_impl::find_or_create_queue_unlocked(const endpoint_type& _target) { - queue_iterator_type target_queue_iterator = queues_.find(_target); - if (target_queue_iterator == queues_.end()) { - target_queue_iterator = queues_.insert(queues_.begin(), - std::make_pair( - _target, - std::make_pair(std::size_t(0), - std::deque()) - )); - } - return target_queue_iterator; -} + bool must_erase(false); -template -std::shared_ptr server_endpoint_impl::find_or_create_train_unlocked( - const endpoint_type& _target) { - auto train_iter = trains_.find(_target); - if (train_iter == trains_.end()) { - train_iter = trains_.insert(trains_.begin(), - std::make_pair(_target, std::make_shared(this->service_))); + auto &its_data = _it->second; + its_data.queue_.push_back(std::make_pair(_train->buffer_, 0)); + its_data.queue_size_ += _train->buffer_->size(); + + if (_queue_size_zero_on_entry && !its_data.queue_.empty()) { // no writing in progress + must_erase = send_queued(_it); } - return train_iter->second; + + return must_erase; } template -bool server_endpoint_impl::flush( - endpoint_type _target, - const std::shared_ptr& _train) { +bool server_endpoint_impl::flush(target_data_iterator_type _it) { + + bool has_queued(true); + bool is_current_train(true); + auto &its_data = _it->second; + std::lock_guard its_lock(mutex_); - bool is_flushed = false; - if (!_train->buffer_->empty()) { - const queue_iterator_type target_queue_iterator = queues_.find(_target); - if (target_queue_iterator != queues_.end()) { - const bool queue_size_zero_on_entry(target_queue_iterator->second.second.empty()); - queue_train(target_queue_iterator, _train, queue_size_zero_on_entry); - is_flushed = true; - } else { - std::stringstream ss; - ss << "sei::flush couldn't find target queue, won't queue train to: " - << get_remote_information(_target) << " passengers: "; - for (const auto& p : _train->passengers_) { - ss << "[" << std::hex << std::setw(4) << std::setfill('0') - << p.first << ":" << p.second << "] "; + + auto its_train(its_data.train_); + if (!its_data.dispatched_trains_.empty()) { + + auto its_dispatched = its_data.dispatched_trains_.begin(); + if (its_dispatched->first <= its_train->departure_) { + + is_current_train = false; + its_train = its_dispatched->second.front(); + its_dispatched->second.pop_front(); + if (its_dispatched->second.empty()) { + + its_data.dispatched_trains_.erase(its_dispatched); } - VSOMEIP_WARNING << ss.str(); } } - return is_flushed; + + if (!its_train->buffer_->empty()) { + + queue_train(_it, its_train, its_data.queue_.empty()); + + // Reset current train if necessary + if (is_current_train) { + its_train->reset(); + } + } else { + has_queued = false; + } + + if (!is_current_train || !its_data.dispatched_trains_.empty()) { + + auto its_now(std::chrono::steady_clock::now()); + start_dispatch_timer(_it, its_now); + } + + return (has_queued); } template @@ -599,7 +611,7 @@ void server_endpoint_impl::connect_cbk( template void server_endpoint_impl::send_cbk( - const queue_iterator_type _queue_iterator, + const target_data_iterator_type _it, boost::system::error_code const &_error, std::size_t _bytes) { (void)_bytes; @@ -623,11 +635,11 @@ void server_endpoint_impl::send_cbk( ++stp_hndlr_iter; continue; } - for (const auto& q : queues_) { - for (const auto& msg : q.second.second ) { + for (const auto& t : targets_) { + for (const auto& e : t.second.queue_ ) { const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*msg)[VSOMEIP_SERVICE_POS_MIN], - (*msg)[VSOMEIP_SERVICE_POS_MAX]); + (*e.first)[VSOMEIP_SERVICE_POS_MIN], + (*e.first)[VSOMEIP_SERVICE_POS_MAX]); if (its_service == its_stopped_service) { found_service_msg = true; break; @@ -639,14 +651,13 @@ void server_endpoint_impl::send_cbk( } if (found_service_msg) { ++stp_hndlr_iter; - found_service_msg = false; } else { // all messages of the to be stopped service have been sent auto handler = stp_hndlr_iter->second; auto ptr = this->shared_from_this(); - #ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) endpoint_impl:: - #endif - service_.post([ptr, handler, its_stopped_service](){ +#endif + io_.post([ptr, handler, its_stopped_service](){ handler(ptr, its_stopped_service); }); stp_hndlr_iter = prepare_stop_handlers_.erase(stp_hndlr_iter); @@ -660,22 +671,18 @@ void server_endpoint_impl::send_cbk( // prepare_stop_handlers have been queued ensure to call them as well check_if_all_msgs_for_stopped_service_are_sent(); } - if (std::all_of(queues_.begin(), queues_.end(), [&] - #ifndef _WIN32 - (const typename queue_type::value_type& q) - #else - (const std::pair>>& q) - #endif - { return q.second.second.empty(); })) { + if (std::all_of(targets_.begin(), targets_.end(), + [&](const typename target_data_type::value_type &_t) + { return _t.second.queue_.empty(); })) { // all outstanding response have been sent. auto found_cbk = prepare_stop_handlers_.find(ANY_SERVICE); if (found_cbk != prepare_stop_handlers_.end()) { auto handler = found_cbk->second; auto ptr = this->shared_from_this(); - #ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) endpoint_impl:: - #endif - service_.post([ptr, handler](){ +#endif + io_.post([ptr, handler](){ handler(ptr, ANY_SERVICE); }); prepare_stop_handlers_.erase(found_cbk); @@ -683,27 +690,30 @@ void server_endpoint_impl::send_cbk( } }; - auto& its_qpair = _queue_iterator->second; + auto& its_data = _it->second; if (!_error) { - its_qpair.first -= its_qpair.second.front()->size(); - its_qpair.second.pop_front(); + its_data.queue_size_ -= its_data.queue_.front().first->size(); + its_data.queue_.pop_front(); + + update_last_departure(its_data); if (!prepare_stop_handlers_.empty() && !endpoint_impl::sending_blocked_) { // only one service instance is stopped check_if_all_msgs_for_stopped_service_are_sent(); } - if (its_qpair.second.size() > 0) { - send_queued(_queue_iterator); + if (!its_data.queue_.empty()) { + (void)send_queued(_it); } else if (!prepare_stop_handlers_.empty() && endpoint_impl::sending_blocked_) { // endpoint is shutting down completely - queues_.erase(_queue_iterator); + cancel_dispatch_timer(_it); + targets_.erase(_it); check_if_all_queues_are_empty(); } } else { message_buffer_ptr_t its_buffer; - if (_queue_iterator->second.second.size()) { - its_buffer = _queue_iterator->second.second.front(); + if (its_data.queue_.size()) { + its_buffer = its_data.queue_.front().first; } service_t its_service(0); method_t its_method(0); @@ -727,14 +737,15 @@ void server_endpoint_impl::send_cbk( // delete remaining outstanding responses VSOMEIP_WARNING << "sei::send_cbk received error: " << _error.message() << " (" << std::dec << _error.value() << ") " - << get_remote_information(_queue_iterator) << " " - << std::dec << _queue_iterator->second.second.size() << " " - << std::dec << _queue_iterator->second.first << " (" + << get_remote_information(_it) << " " + << std::dec << its_data.queue_.size() << " " + << std::dec << its_data.queue_size_ << " (" << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_method << "." << std::hex << std::setw(4) << std::setfill('0') << its_session << "]"; - queues_.erase(_queue_iterator); + cancel_dispatch_timer(_it); + targets_.erase(_it); if (!prepare_stop_handlers_.empty()) { if (endpoint_impl::sending_blocked_) { // endpoint is shutting down completely, ensure to call @@ -751,32 +762,92 @@ void server_endpoint_impl::send_cbk( template void server_endpoint_impl::flush_cbk( - endpoint_type _target, - const std::shared_ptr& _train, const boost::system::error_code &_error_code) { + target_data_iterator_type _it, + const boost::system::error_code &_error_code) { + if (!_error_code) { - (void) flush(_target, _train); + + (void) flush(_it); } } template size_t server_endpoint_impl::get_queue_size() const { size_t its_queue_size(0); - { std::lock_guard its_lock(mutex_); - for (const auto &q : queues_) { - its_queue_size += q.second.second.size(); + for (const auto &t : targets_) { + its_queue_size += t.second.queue_size_; } } + return (its_queue_size); +} + +template +void server_endpoint_impl::start_dispatch_timer( + target_data_iterator_type _it, + const std::chrono::steady_clock::time_point &_now) { + + auto &its_data = _it->second; + std::shared_ptr its_train(its_data.train_); + + if (!its_data.dispatched_trains_.empty()) { + + auto its_dispatched = its_data.dispatched_trains_.begin(); + if (its_dispatched->first < its_train->departure_) { - return its_queue_size; + its_train = its_dispatched->second.front(); + } + } + + std::chrono::nanoseconds its_offset; + if (its_train->departure_ > _now) { + + its_offset = std::chrono::duration_cast( + its_train->departure_ - _now); + } else { // already departure time + + its_offset = std::chrono::nanoseconds::zero(); + } + +#if defined(__linux__) || defined(ANDROID) + its_data.dispatch_timer_->expires_from_now(its_offset); +#else + its_data.dispatch_timer_->expires_from_now( + std::chrono::duration_cast< + std::chrono::steady_clock::duration>(its_offset)); +#endif + its_data.dispatch_timer_->async_wait( + std::bind(&server_endpoint_impl::flush_cbk, + this->shared_from_this(), _it, std::placeholders::_1)); +} + +template +void server_endpoint_impl::cancel_dispatch_timer( + target_data_iterator_type _it) { + + boost::system::error_code ec; + _it->second.dispatch_timer_->cancel(ec); +} + +template +void server_endpoint_impl::update_last_departure( + endpoint_data_type &_data) { + + _data.last_departure_ = std::chrono::steady_clock::now(); + _data.has_last_departure_ = true; } // Instantiate template -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) +#if VSOMEIP_BOOST_VERSION < 106600 template class server_endpoint_impl; +template class server_endpoint_impl; +#else +template class server_endpoint_impl; +template class server_endpoint_impl; +#endif #endif template class server_endpoint_impl; -template class server_endpoint_impl; } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp index f88d2a2..588d252 100644 --- a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -26,7 +26,7 @@ tcp_client_endpoint_impl::tcp_client_endpoint_impl( const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration) : tcp_client_endpoint_base_impl(_endpoint_host, _routing_host, _local, _remote, _io, @@ -78,7 +78,7 @@ void tcp_client_endpoint_impl::restart(bool _force) { if (!_force && self->state_ == cei_state_e::CONNECTING) { std::chrono::steady_clock::time_point its_current = std::chrono::steady_clock::now(); - long its_connect_duration = std::chrono::duration_cast( + std::int64_t its_connect_duration = std::chrono::duration_cast( its_current - self->connect_timepoint_).count(); if (self->aborted_restart_count_ < self->tcp_restart_aborts_max_ && its_connect_duration < self->tcp_connect_time_max_) { @@ -102,26 +102,26 @@ void tcp_client_endpoint_impl::restart(bool _force) { self->reconnect_counter_ = 0; { std::lock_guard its_lock(self->mutex_); - for (const auto&m : self->queue_) { + for (const auto &q : self->queue_) { const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*m)[VSOMEIP_SERVICE_POS_MIN], - (*m)[VSOMEIP_SERVICE_POS_MAX]); + (*q.first)[VSOMEIP_SERVICE_POS_MIN], + (*q.first)[VSOMEIP_SERVICE_POS_MAX]); const method_t its_method = VSOMEIP_BYTES_TO_WORD( - (*m)[VSOMEIP_METHOD_POS_MIN], - (*m)[VSOMEIP_METHOD_POS_MAX]); + (*q.first)[VSOMEIP_METHOD_POS_MIN], + (*q.first)[VSOMEIP_METHOD_POS_MAX]); const client_t its_client = VSOMEIP_BYTES_TO_WORD( - (*m)[VSOMEIP_CLIENT_POS_MIN], - (*m)[VSOMEIP_CLIENT_POS_MAX]); + (*q.first)[VSOMEIP_CLIENT_POS_MIN], + (*q.first)[VSOMEIP_CLIENT_POS_MAX]); const session_t its_session = VSOMEIP_BYTES_TO_WORD( - (*m)[VSOMEIP_SESSION_POS_MIN], - (*m)[VSOMEIP_SESSION_POS_MAX]); + (*q.first)[VSOMEIP_SESSION_POS_MIN], + (*q.first)[VSOMEIP_SESSION_POS_MAX]); VSOMEIP_WARNING << "tce::restart: dropping message: " << "remote:" << self->get_address_port_remote() << " (" << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_method << "." << std::hex << std::setw(4) << std::setfill('0') << its_session << "]" - << " size: " << std::dec << m->size(); + << " size: " << std::dec << q.first->size(); } self->queue_.clear(); self->queue_size_ = 0; @@ -136,6 +136,7 @@ void tcp_client_endpoint_impl::restart(bool _force) { } void tcp_client_endpoint_impl::connect() { + start_connecting_timer(); std::lock_guard its_lock(socket_mutex_); boost::system::error_code its_error; socket_->open(remote_.protocol(), its_error); @@ -172,7 +173,7 @@ void tcp_client_endpoint_impl::connect() { << " remote:" << get_address_port_remote(); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) // If specified, bind to device std::string its_device(configuration_->get_device()); if (its_device != "") { @@ -191,14 +192,13 @@ void tcp_client_endpoint_impl::connect() { if(its_bind_error) { VSOMEIP_WARNING << "tcp_client_endpoint::connect: " "Error binding socket: " << its_bind_error.message() - << " local: " << local_.address().to_string() - << ":" << std::dec << local_.port() + << " local: " << get_address_port_local() << " remote:" << get_address_port_remote(); std::shared_ptr its_host = endpoint_host_.lock(); if (its_host) { // set new client port depending on service / instance / remote port - if (!its_host->on_bind_error(shared_from_this(), remote_port_)) { + if (!its_host->on_bind_error(shared_from_this(), remote_address_, remote_port_)) { VSOMEIP_WARNING << "tcp_client_endpoint::connect: " "Failed to set new local port for tce: " << " local: " << local_.address().to_string() @@ -220,15 +220,12 @@ void tcp_client_endpoint_impl::connect() { } catch (const std::exception &e) { VSOMEIP_ERROR << "tcp_client_endpoint_impl::connect: " << e.what() - << " local: " << local_.address().to_string() - << ":" << std::dec << local_.port() + << " local: " << get_address_port_local() << " remote:" << get_address_port_remote(); } return; } - return; } - state_ = cei_state_e::CONNECTING; connect_timepoint_ = std::chrono::steady_clock::now(); aborted_restart_count_ = 0; @@ -316,26 +313,26 @@ void tcp_client_endpoint_impl::receive(message_buffer_ptr_t _recv_buffer, } } -void tcp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { +void tcp_client_endpoint_impl::send_queued(std::pair &_entry) { const service_t its_service = VSOMEIP_BYTES_TO_WORD( - (*_buffer)[VSOMEIP_SERVICE_POS_MIN], - (*_buffer)[VSOMEIP_SERVICE_POS_MAX]); + (*_entry.first)[VSOMEIP_SERVICE_POS_MIN], + (*_entry.first)[VSOMEIP_SERVICE_POS_MAX]); const method_t its_method = VSOMEIP_BYTES_TO_WORD( - (*_buffer)[VSOMEIP_METHOD_POS_MIN], - (*_buffer)[VSOMEIP_METHOD_POS_MAX]); + (*_entry.first)[VSOMEIP_METHOD_POS_MIN], + (*_entry.first)[VSOMEIP_METHOD_POS_MAX]); const client_t its_client = VSOMEIP_BYTES_TO_WORD( - (*_buffer)[VSOMEIP_CLIENT_POS_MIN], - (*_buffer)[VSOMEIP_CLIENT_POS_MAX]); + (*_entry.first)[VSOMEIP_CLIENT_POS_MIN], + (*_entry.first)[VSOMEIP_CLIENT_POS_MAX]); const session_t its_session = VSOMEIP_BYTES_TO_WORD( - (*_buffer)[VSOMEIP_SESSION_POS_MIN], - (*_buffer)[VSOMEIP_SESSION_POS_MAX]); + (*_entry.first)[VSOMEIP_SESSION_POS_MIN], + (*_entry.first)[VSOMEIP_SESSION_POS_MAX]); if (has_enabled_magic_cookies_) { const std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); if (std::chrono::duration_cast( now - last_cookie_sent_) > std::chrono::milliseconds(10000)) { - send_magic_cookie(_buffer); + send_magic_cookie(_entry.first); last_cookie_sent_ = now; } } @@ -347,7 +344,7 @@ void tcp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { << std::dec << remote_.port() << ">::sq: "; for (std::size_t i = 0; i < _buffer->size(); i++) msg << std::hex << std::setw(2) << std::setfill('0') - << (int)(*_buffer)[i] << " "; + << (int)(*_entry.first)[i] << " "; VSOMEIP_INFO << msg.str(); #endif { @@ -359,13 +356,13 @@ void tcp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { } boost::asio::async_write( *socket_, - boost::asio::buffer(*_buffer), + boost::asio::buffer(*_entry.first), std::bind( &tcp_client_endpoint_impl::write_completion_condition, std::static_pointer_cast(shared_from_this()), std::placeholders::_1, std::placeholders::_2, - _buffer->size(), + _entry.first->size(), its_service, its_method, its_client, its_session, std::chrono::steady_clock::now()), strand_.wrap( @@ -374,7 +371,7 @@ void tcp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { shared_from_this(), std::placeholders::_1, std::placeholders::_2, - _buffer + _entry.first )) ); } @@ -510,7 +507,7 @@ void tcp_client_endpoint_impl::receive_cbk( if (its_host) { std::uint32_t its_missing_capacity(0); if (!_error && 0 < _bytes) { - if (_recv_buffer_size + _bytes < _recv_buffer_size) { + if (_recv_buffer_size + _bytes > _recv_buffer->size()) { VSOMEIP_ERROR << "receive buffer overflow in tcp client endpoint ~> abort!"; return; } @@ -548,9 +545,9 @@ void tcp_client_endpoint_impl::receive_cbk( if (!has_enabled_magic_cookies_) { its_host->on_message(&(*_recv_buffer)[its_iteration_gap], current_message_size, this, - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } else { @@ -558,9 +555,9 @@ void tcp_client_endpoint_impl::receive_cbk( if (!is_magic_cookie(_recv_buffer, its_iteration_gap)) { its_host->on_message(&(*_recv_buffer)[its_iteration_gap], current_message_size, this, - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } @@ -597,11 +594,12 @@ void tcp_client_endpoint_impl::receive_cbk( << " remote: " << get_address_port_remote(); // ensure to send back a message w/ wrong protocol version its_lock.unlock(); + its_host->on_message(&(*_recv_buffer)[its_iteration_gap], VSOMEIP_SOMEIP_HEADER_SIZE + 8, this, - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); its_lock.lock(); @@ -761,8 +759,7 @@ void tcp_client_endpoint_impl::calculate_shrink_count(const message_buffer_ptr_t } -const std::string tcp_client_endpoint_impl::get_address_port_remote() const { - boost::system::error_code ec; +std::string tcp_client_endpoint_impl::get_address_port_remote() const { std::string its_address_port; its_address_port.reserve(21); boost::asio::ip::address its_address; @@ -774,7 +771,7 @@ const std::string tcp_client_endpoint_impl::get_address_port_remote() const { return its_address_port; } -const std::string tcp_client_endpoint_impl::get_address_port_local() const { +std::string tcp_client_endpoint_impl::get_address_port_local() const { std::string its_address_port; its_address_port.reserve(21); boost::system::error_code ec; @@ -793,7 +790,6 @@ void tcp_client_endpoint_impl::handle_recv_buffer_exception( const std::exception &_e, const message_buffer_ptr_t& _recv_buffer, std::size_t _recv_buffer_size) { - boost::system::error_code ec; std::stringstream its_message; its_message <<"tcp_client_endpoint_impl::connection catched exception" @@ -877,13 +873,16 @@ void tcp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, if (!_error) { std::lock_guard its_lock(mutex_); if (queue_.size() > 0) { - queue_size_ -= queue_.front()->size(); + queue_size_ -= queue_.front().first->size(); queue_.pop_front(); - auto its_buffer = get_front(); - if (its_buffer) { + + update_last_departure(); + + auto its_entry = get_front(); + if (its_entry.first) { auto self = std::dynamic_pointer_cast< tcp_client_endpoint_impl >(shared_from_this()); strand_.dispatch( - [self, its_buffer]() { self->send_queued(its_buffer);} + [self, &its_entry]() { self->send_queued(its_entry);} ); } } diff --git a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp index 37db3f5..f23e9be 100644 --- a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp @@ -1,5 +1,5 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -26,7 +26,7 @@ tcp_server_endpoint_impl::tcp_server_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration) : tcp_server_endpoint_base_impl(_endpoint_host, _routing_host, _local, _io, _configuration->get_max_message_size_reliable(_local.address().to_string(), _local.port()), @@ -41,11 +41,16 @@ tcp_server_endpoint_impl::tcp_server_endpoint_impl( boost::system::error_code ec; acceptor_.open(_local.protocol(), ec); - boost::asio::detail::throw_error(ec, "acceptor open"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": open failed (" << ec.message() << ")"; + acceptor_.set_option(boost::asio::socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "acceptor set_option"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": set reuse address option failed (" << ec.message() << ")"; -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) // If specified, bind to device std::string its_device(configuration_->get_device()); if (its_device != "") { @@ -57,9 +62,14 @@ tcp_server_endpoint_impl::tcp_server_endpoint_impl( #endif acceptor_.bind(_local, ec); - boost::asio::detail::throw_error(ec, "acceptor bind"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": bind failed (" << ec.message() << ")"; + acceptor_.listen(boost::asio::socket_base::max_connections, ec); - boost::asio::detail::throw_error(ec, "acceptor listen"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": listen failed (" << ec.message() << ")"; } tcp_server_endpoint_impl::~tcp_server_endpoint_impl() { @@ -76,7 +86,7 @@ void tcp_server_endpoint_impl::start() { std::dynamic_pointer_cast( shared_from_this()), max_message_size_, buffer_shrink_threshold_, has_enabled_magic_cookies_, - service_, send_timeout_); + io_, send_timeout_); { std::unique_lock its_socket_lock(new_connection->get_socket_lock()); @@ -121,44 +131,47 @@ bool tcp_server_endpoint_impl::send_error( bool ret(false); std::lock_guard its_lock(mutex_); const endpoint_type its_target(_target->get_address(), _target->get_port()); - const queue_iterator_type target_queue_iterator(find_or_create_queue_unlocked(its_target)); - auto& its_qpair = target_queue_iterator->second; - const bool queue_size_zero_on_entry(its_qpair.second.empty()); + const auto its_target_iterator(find_or_create_target_unlocked(its_target)); + auto &its_data = its_target_iterator->second; + const bool queue_size_zero_on_entry(its_data.queue_.empty()); if (check_message_size(nullptr, _size, its_target) == endpoint_impl::cms_ret_e::MSG_OK && - check_queue_limit(_data, _size, its_qpair.first)) { - its_qpair.second.emplace_back( - std::make_shared(_data, _data + _size)); - its_qpair.first += _size; + check_queue_limit(_data, _size, its_data.queue_size_)) { + its_data.queue_.emplace_back( + std::make_pair(std::make_shared(_data, _data + _size), 0)); + its_data.queue_size_ += _size; if (queue_size_zero_on_entry) { // no writing in progress - send_queued(target_queue_iterator); + send_queued(its_target_iterator); } ret = true; } return ret; } -void tcp_server_endpoint_impl::send_queued(const queue_iterator_type _queue_iterator) { +bool tcp_server_endpoint_impl::send_queued(const target_data_iterator_type _it) { + + bool must_erase(false); connection::ptr its_connection; { std::lock_guard its_lock(connections_mutex_); - auto connection_iterator = connections_.find(_queue_iterator->first); + auto connection_iterator = connections_.find(_it->first); if (connection_iterator != connections_.end()) { its_connection = connection_iterator->second; } else { VSOMEIP_INFO << "Didn't find connection: " - << _queue_iterator->first.address().to_string() << ":" << std::dec - << static_cast(_queue_iterator->first.port()) + << _it->first.address().to_string() << ":" << std::dec + << static_cast(_it->first.port()) << " dropping outstanding messages (" << std::dec - << _queue_iterator->second.second.size() << ")."; + << _it->second.queue_.size() << ")."; - if (_queue_iterator->second.second.size()) { + if (_it->second.queue_.size()) { std::set its_services; // check all outstanding messages of this connection // whether stop handlers need to be called - for (const auto &its_buffer : _queue_iterator->second.second) { + for (const auto &its_q : _it->second.queue_) { + auto its_buffer(its_q.first); if (its_buffer && its_buffer->size() > VSOMEIP_SESSION_POS_MAX) { service_t its_service = VSOMEIP_BYTES_TO_WORD( (*its_buffer)[VSOMEIP_SERVICE_POS_MIN], @@ -176,7 +189,7 @@ void tcp_server_endpoint_impl::send_queued(const queue_iterator_type _queue_iter << its_service; auto handler = found_cbk->second; auto ptr = this->shared_from_this(); - service_.post([ptr, handler, its_service](){ + io_.post([ptr, handler, its_service](){ handler(ptr, its_service); }); prepare_stop_handlers_.erase(found_cbk); @@ -184,12 +197,14 @@ void tcp_server_endpoint_impl::send_queued(const queue_iterator_type _queue_iter } } - queues_.erase(_queue_iterator->first); + must_erase = true; } } if (its_connection) { - its_connection->send_queued(_queue_iterator); + its_connection->send_queued(_it); } + + return (must_erase); } void tcp_server_endpoint_impl::get_configured_times_from_endpoint( @@ -202,7 +217,7 @@ void tcp_server_endpoint_impl::get_configured_times_from_endpoint( _debouncing, _maximum_retention); } -bool tcp_server_endpoint_impl::is_established(const std::shared_ptr& _endpoint) { +bool tcp_server_endpoint_impl::is_established_to(const std::shared_ptr& _endpoint) { bool is_connected = false; endpoint_type endpoint(_endpoint->get_address(), _endpoint->get_port()); { @@ -274,7 +289,7 @@ void tcp_server_endpoint_impl::accept_cbk(const connection::ptr& _connection, << _error.message() << " (" << std::dec << _error.value() << ") Will try to accept again in 1000ms"; std::shared_ptr its_timer = - std::make_shared(service_, + std::make_shared(io_, std::chrono::milliseconds(1000)); auto its_ep = std::dynamic_pointer_cast( shared_from_this()); @@ -288,6 +303,7 @@ void tcp_server_endpoint_impl::accept_cbk(const connection::ptr& _connection, } std::uint16_t tcp_server_endpoint_impl::get_local_port() const { + return local_port_; } @@ -308,9 +324,9 @@ tcp_server_endpoint_impl::connection::connection( std::uint32_t _recv_buffer_size_initial, std::uint32_t _buffer_shrink_threshold, bool _magic_cookies_enabled, - boost::asio::io_service &_io_service, + boost::asio::io_context &_io, std::chrono::milliseconds _send_timeout) : - socket_(_io_service), + socket_(_io), server_(_server), max_message_size_(_max_message_size), recv_buffer_size_initial_(_recv_buffer_size_initial), @@ -326,20 +342,33 @@ tcp_server_endpoint_impl::connection::connection( send_timeout_warning_(_send_timeout / 2) { } +tcp_server_endpoint_impl::connection::~connection() { + + auto its_server(server_.lock()); + if (its_server) { + auto its_routing_host(its_server->routing_host_.lock()); + if (its_routing_host) { + its_routing_host->remove_subscriptions( + its_server->local_port_, + remote_address_, remote_port_); + } + } +} + tcp_server_endpoint_impl::connection::ptr tcp_server_endpoint_impl::connection::create( const std::weak_ptr& _server, std::uint32_t _max_message_size, std::uint32_t _buffer_shrink_threshold, bool _magic_cookies_enabled, - boost::asio::io_service & _io_service, + boost::asio::io_context &_io, std::chrono::milliseconds _send_timeout) { const std::uint32_t its_initial_receveive_buffer_size = VSOMEIP_SOMEIP_HEADER_SIZE + 8 + MAGIC_COOKIE_SIZE + 8; return ptr(new connection(_server, _max_message_size, its_initial_receveive_buffer_size, _buffer_shrink_threshold, _magic_cookies_enabled, - _io_service, _send_timeout)); + _io, _send_timeout)); } tcp_server_endpoint_impl::socket_type & @@ -360,7 +389,13 @@ void tcp_server_endpoint_impl::connection::receive() { std::lock_guard its_lock(socket_mutex_); if(socket_.is_open()) { const std::size_t its_capacity(recv_buffer_.capacity()); - size_t buffer_size = its_capacity - recv_buffer_size_; + if (recv_buffer_size_ > its_capacity) { + VSOMEIP_ERROR << __func__ << "Received buffer size is greater than the buffer capacity!" + << " recv_buffer_size_: " << recv_buffer_size_ + << " its_capacity: " << its_capacity; + return; + } + size_t left_buffer_size = its_capacity - recv_buffer_size_; try { if (missing_capacity_) { if (missing_capacity_ > MESSAGE_SIZE_UNLIMITED) { @@ -369,6 +404,7 @@ void tcp_server_endpoint_impl::connection::receive() { } const std::size_t its_required_capacity(recv_buffer_size_ + missing_capacity_); if (its_capacity < its_required_capacity) { + // Make the resize to its_required_capacity recv_buffer_.reserve(its_required_capacity); recv_buffer_.resize(its_required_capacity, 0x0); if (recv_buffer_.size() > 1048576) { @@ -378,14 +414,16 @@ void tcp_server_endpoint_impl::connection::receive() { << " remote: " << get_address_port_remote(); } } - buffer_size = missing_capacity_; + left_buffer_size = missing_capacity_; missing_capacity_ = 0; } else if (buffer_shrink_threshold_ && shrink_count_ > buffer_shrink_threshold_ && recv_buffer_size_ == 0) { + // In this case, make the resize to recv_buffer_size_initial_ recv_buffer_.resize(recv_buffer_size_initial_, 0x0); recv_buffer_.shrink_to_fit(); - buffer_size = recv_buffer_size_initial_; + // And set buffer_size to recv_buffer_size_initial_, the same of our resize + left_buffer_size = recv_buffer_size_initial_; shrink_count_ = 0; } } catch (const std::exception &e) { @@ -393,7 +431,7 @@ void tcp_server_endpoint_impl::connection::receive() { // don't start receiving again return; } - socket_.async_receive(boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size), + socket_.async_receive(boost::asio::buffer(&recv_buffer_[recv_buffer_size_], left_buffer_size), std::bind(&tcp_server_endpoint_impl::connection::receive_cbk, shared_from_this(), std::placeholders::_1, std::placeholders::_2)); @@ -410,14 +448,15 @@ void tcp_server_endpoint_impl::connection::stop() { } void tcp_server_endpoint_impl::connection::send_queued( - const queue_iterator_type _queue_iterator) { + const target_data_iterator_type _it) { + std::shared_ptr its_server(server_.lock()); if (!its_server) { VSOMEIP_TRACE << "tcp_server_endpoint_impl::connection::send_queued " " couldn't lock server_"; return; } - message_buffer_ptr_t its_buffer = _queue_iterator->second.second.front(); + message_buffer_ptr_t its_buffer = _it->second.queue_.front().first; const service_t its_service = VSOMEIP_BYTES_TO_WORD( (*its_buffer)[VSOMEIP_SERVICE_POS_MIN], (*its_buffer)[VSOMEIP_SERVICE_POS_MAX]); @@ -437,7 +476,7 @@ void tcp_server_endpoint_impl::connection::send_queued( now - last_cookie_sent_) > std::chrono::milliseconds(10000)) { if (send_magic_cookie(its_buffer)) { last_cookie_sent_ = now; - _queue_iterator->second.first += sizeof(SERVICE_COOKIE); + _it->second.queue_size_ += sizeof(SERVICE_COOKIE); } } } @@ -459,15 +498,16 @@ void tcp_server_endpoint_impl::connection::send_queued( std::chrono::steady_clock::now()), std::bind(&tcp_server_endpoint_base_impl::send_cbk, its_server, - _queue_iterator, + _it, std::placeholders::_1, std::placeholders::_2)); } } void tcp_server_endpoint_impl::connection::send_queued_sync( - const queue_iterator_type _queue_iterator) { - message_buffer_ptr_t its_buffer = _queue_iterator->second.second.front(); + const target_data_iterator_type _it) { + + message_buffer_ptr_t its_buffer = _it->second.queue_.front().first; if (magic_cookies_enabled_) { const std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); @@ -475,7 +515,7 @@ void tcp_server_endpoint_impl::connection::send_queued_sync( now - last_cookie_sent_) > std::chrono::milliseconds(10000)) { if (send_magic_cookie(its_buffer)) { last_cookie_sent_ = now; - _queue_iterator->second.first += sizeof(SERVICE_COOKIE); + _it->second.queue_size_ += sizeof(SERVICE_COOKIE); } } } @@ -587,36 +627,29 @@ void tcp_server_endpoint_impl::connection::receive_cbk( recv_buffer_[its_iteration_gap + VSOMEIP_CLIENT_POS_MIN], recv_buffer_[its_iteration_gap + VSOMEIP_CLIENT_POS_MAX]); if (its_client != MAGIC_COOKIE_CLIENT) { - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - recv_buffer_[its_iteration_gap + VSOMEIP_SERVICE_POS_MIN], - recv_buffer_[its_iteration_gap + VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - recv_buffer_[its_iteration_gap + VSOMEIP_METHOD_POS_MIN], - recv_buffer_[its_iteration_gap + VSOMEIP_METHOD_POS_MAX]); const session_t its_session = VSOMEIP_BYTES_TO_WORD( recv_buffer_[its_iteration_gap + VSOMEIP_SESSION_POS_MIN], recv_buffer_[its_iteration_gap + VSOMEIP_SESSION_POS_MAX]); - - std::lock_guard its_requests_guard(its_server->requests_mutex_); - its_server->requests_[its_client] - [std::make_tuple(its_service, its_method, its_session)] = remote_; + its_server->clients_mutex_.lock(); + its_server->clients_[its_client][its_session] = remote_; + its_server->clients_mutex_.unlock(); } } if (!magic_cookies_enabled_) { its_host->on_message(&recv_buffer_[its_iteration_gap], current_message_size, its_server.get(), - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } else { // Only call on_message without a magic cookie in front of the buffer! if (!is_magic_cookie(its_iteration_gap)) { its_host->on_message(&recv_buffer_[its_iteration_gap], current_message_size, its_server.get(), - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } } @@ -677,9 +710,9 @@ void tcp_server_endpoint_impl::connection::receive_cbk( // ensure to send back a error message w/ wrong protocol version its_host->on_message(&recv_buffer_[its_iteration_gap], VSOMEIP_SOMEIP_HEADER_SIZE + 8, its_server.get(), - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } else if (!utility::is_valid_message_type(static_cast( recv_buffer_[its_iteration_gap + VSOMEIP_MESSAGE_TYPE_POS]))) { @@ -814,7 +847,7 @@ void tcp_server_endpoint_impl::connection::set_remote_info( remote_port_ = _remote.port(); } -const std::string tcp_server_endpoint_impl::connection::get_address_port_remote() const { +std::string tcp_server_endpoint_impl::connection::get_address_port_remote() const { std::string its_address_port; its_address_port.reserve(21); boost::system::error_code ec; @@ -824,7 +857,7 @@ const std::string tcp_server_endpoint_impl::connection::get_address_port_remote( return its_address_port; } -const std::string tcp_server_endpoint_impl::connection::get_address_port_local() const { +std::string tcp_server_endpoint_impl::connection::get_address_port_local() const { std::string its_address_port; its_address_port.reserve(21); boost::system::error_code ec; @@ -954,7 +987,7 @@ void tcp_server_endpoint_impl::print_status() { VSOMEIP_INFO << "status tse: " << std::dec << local_port_ << " connections: " << std::dec << its_connections.size() - << " queues: " << std::dec << queues_.size(); + << " targets: " << std::dec << targets_.size(); for (const auto &c : its_connections) { std::size_t its_data_size(0); std::size_t its_queue_size(0); @@ -963,10 +996,10 @@ void tcp_server_endpoint_impl::print_status() { std::unique_lock c_s_lock(c.second->get_socket_lock()); its_recv_size = c.second->get_recv_buffer_capacity(); } - auto found_queue = queues_.find(c.first); - if (found_queue != queues_.end()) { - its_queue_size = found_queue->second.second.size(); - its_data_size = found_queue->second.first; + auto found_queue = targets_.find(c.first); + if (found_queue != targets_.end()) { + its_queue_size = found_queue->second.queue_.size(); + its_data_size = found_queue->second.queue_size_; } VSOMEIP_INFO << "status tse: client: " << c.second->get_address_port_remote() @@ -977,10 +1010,10 @@ void tcp_server_endpoint_impl::print_status() { } std::string tcp_server_endpoint_impl::get_remote_information( - const queue_iterator_type _queue_iterator) const { + const target_data_iterator_type _it) const { boost::system::error_code ec; - return _queue_iterator->first.address().to_string(ec) + ":" - + std::to_string(_queue_iterator->first.port()); + return _it->first.address().to_string(ec) + ":" + + std::to_string(_it->first.port()); } std::string tcp_server_endpoint_impl::get_remote_information( diff --git a/implementation/endpoints/src/tp.cpp b/implementation/endpoints/src/tp.cpp index 0a2578d..f5a2f45 100644 --- a/implementation/endpoints/src/tp.cpp +++ b/implementation/endpoints/src/tp.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -16,7 +16,7 @@ #include "../../configuration/include/internal.hpp" #endif // ANDROID -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #else #include @@ -26,10 +26,10 @@ namespace vsomeip_v3 { namespace tp { -const std::uint16_t tp::tp_max_segment_length_ = 1392; +tp_split_messages_t +tp::tp_split_message(const std::uint8_t * const _data, std::uint32_t _size, + std::uint16_t _max_segment_length) { -tp_split_messages_t tp::tp_split_message(const std::uint8_t * const _data, - std::uint32_t _size) { tp_split_messages_t split_messages; if (_size < VSOMEIP_MAX_UDP_MESSAGE_SIZE) { @@ -38,16 +38,15 @@ tp_split_messages_t tp::tp_split_message(const std::uint8_t * const _data, } const auto data_end = _data + _size; - for (auto current_offset = _data + VSOMEIP_FULL_HEADER_SIZE; current_offset < data_end;) { auto msg = std::make_shared(); - msg->reserve(VSOMEIP_FULL_HEADER_SIZE + sizeof(tp_header_t) + tp_max_segment_length_); + msg->reserve(VSOMEIP_FULL_HEADER_SIZE + sizeof(tp_header_t) + _max_segment_length); // copy the header msg->insert(msg->end(), _data, _data + VSOMEIP_FULL_HEADER_SIZE); // change the message type (*msg)[VSOMEIP_MESSAGE_TYPE_POS] = (*msg)[VSOMEIP_MESSAGE_TYPE_POS] | 0x20; // check if last segment - const auto segment_end = current_offset + tp_max_segment_length_; + const auto segment_end = current_offset + _max_segment_length; const bool is_last_segment = (segment_end >= data_end); // insert tp_header const tp_header_t header = htonl( @@ -63,7 +62,7 @@ tp_split_messages_t tp::tp_split_message(const std::uint8_t * const _data, current_offset = data_end; } else { msg->insert(msg->end(), current_offset, segment_end); - current_offset += tp_max_segment_length_; + current_offset += _max_segment_length; } // update length const length_t its_length = static_cast(msg->size() @@ -75,5 +74,7 @@ tp_split_messages_t tp::tp_split_message(const std::uint8_t * const _data, return split_messages; } +const std::uint16_t tp::tp_max_segment_length_; + } // namespace tp } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/tp_message.cpp b/implementation/endpoints/src/tp_message.cpp index 57696ca..6961511 100644 --- a/implementation/endpoints/src/tp_message.cpp +++ b/implementation/endpoints/src/tp_message.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -18,7 +18,7 @@ #include "../../configuration/include/internal.hpp" #endif // ANDROID -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #else #include diff --git a/implementation/endpoints/src/tp_reassembler.cpp b/implementation/endpoints/src/tp_reassembler.cpp index 07a31e0..49e5731 100644 --- a/implementation/endpoints/src/tp_reassembler.cpp +++ b/implementation/endpoints/src/tp_reassembler.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -23,7 +23,7 @@ namespace vsomeip_v3 { namespace tp { -tp_reassembler::tp_reassembler(std::uint32_t _max_message_size, boost::asio::io_service &_io) : +tp_reassembler::tp_reassembler(std::uint32_t _max_message_size, boost::asio::io_context &_io) : max_message_size_(_max_message_size), cleanup_timer_running_(false), cleanup_timer_(_io) { @@ -175,7 +175,6 @@ void tp_reassembler::cleanup_timer_start(bool _force) { } void tp_reassembler::cleanup_timer_start_unlocked(bool _force) { - boost::system::error_code ec; if (!cleanup_timer_running_ || _force) { cleanup_timer_.expires_from_now(std::chrono::seconds(5)); cleanup_timer_running_ = true; diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp index 3b9a212..5d675f6 100644 --- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp @@ -1,10 +1,11 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include #include +#include #include #include @@ -16,7 +17,6 @@ #include "../../utility/include/utility.hpp" #include "../../utility/include/byteorder.hpp" - namespace vsomeip_v3 { udp_client_endpoint_impl::udp_client_endpoint_impl( @@ -24,7 +24,7 @@ udp_client_endpoint_impl::udp_client_endpoint_impl( const std::shared_ptr& _routing_host, const endpoint_type& _local, const endpoint_type& _remote, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration) : udp_client_endpoint_base_impl(_endpoint_host, _routing_host, _local, _remote, _io, VSOMEIP_MAX_UDP_MESSAGE_SIZE, @@ -53,6 +53,7 @@ bool udp_client_endpoint_impl::is_local() const { } void udp_client_endpoint_impl::connect() { + start_connecting_timer(); std::lock_guard its_lock(socket_mutex_); boost::system::error_code its_error; socket_->open(remote_.protocol(), its_error); @@ -63,11 +64,9 @@ void udp_client_endpoint_impl::connect() { socket_->set_option(boost::asio::socket_base::reuse_address(true), its_error); if (its_error) { VSOMEIP_WARNING << "udp_client_endpoint_impl::connect: couldn't enable " - << "SO_REUSEADDR: " << its_error.message() - << " local port:" << std::dec << local_.port() - << " remote:" << get_address_port_remote(); + << "SO_REUSEADDR: " << its_error.message() << " remote:" + << get_address_port_remote(); } - socket_->set_option(boost::asio::socket_base::receive_buffer_size( udp_receive_buffer_size_), its_error); if (its_error) { @@ -109,12 +108,17 @@ void udp_client_endpoint_impl::connect() { << " remote:" << get_address_port_remote(); } -#ifndef _WIN32 + if (local_.port() == ILLEGAL_PORT) { + // Let the OS assign the port + local_.port(0); + } + +#if defined(__linux__) || defined(ANDROID) // If specified, bind to device std::string its_device(configuration_->get_device()); if (its_device != "") { if (setsockopt(socket_->native_handle(), - SOL_SOCKET, SO_BINDTODEVICE, its_device.c_str(), (socklen_t)its_device.size()) == -1) { + SOL_SOCKET, SO_BINDTODEVICE, its_device.c_str(), socklen_t(its_device.size())) == -1) { VSOMEIP_WARNING << "UDP Client: Could not bind to device \"" << its_device << "\""; } } @@ -135,7 +139,7 @@ void udp_client_endpoint_impl::connect() { std::shared_ptr its_host = endpoint_host_.lock(); if (its_host) { // set new client port depending on service / instance / remote port - if (!its_host->on_bind_error(shared_from_this(), remote_port_)) { + if (!its_host->on_bind_error(shared_from_this(), remote_address_, remote_port_)) { VSOMEIP_WARNING << "udp_client_endpoint::connect: " "Failed to set new local port for uce: " << " local: " << local_.address().to_string() @@ -162,7 +166,6 @@ void udp_client_endpoint_impl::connect() { } return; } - return; } state_ = cei_state_e::CONNECTING; @@ -210,26 +213,44 @@ void udp_client_endpoint_impl::restart(bool _force) { start_connect_timer(); } -void udp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { +void udp_client_endpoint_impl::send_queued(std::pair &_entry) { + static std::chrono::steady_clock::time_point its_last_sent; #if 0 std::stringstream msg; msg << "ucei<" << remote_.address() << ":" << std::dec << remote_.port() << ">::sq: "; for (std::size_t i = 0; i < _buffer->size(); i++) msg << std::hex << std::setw(2) << std::setfill('0') - << (int)(*_buffer)[i] << " "; + << (int)(*_entry.first)[i] << " "; VSOMEIP_INFO << msg.str(); #endif { std::lock_guard its_lock(socket_mutex_); + + // Check whether we need to wait (SOME/IP-TP separation time) + if (_entry.second > 0) { + if (its_last_sent != std::chrono::steady_clock::time_point()) { + const auto its_elapsed + = std::chrono::duration_cast( + std::chrono::steady_clock::now() - its_last_sent).count(); + if (_entry.second > its_elapsed) + std::this_thread::sleep_for( + std::chrono::microseconds(_entry.second - its_elapsed)); + } + its_last_sent = std::chrono::steady_clock::now(); + } else { + its_last_sent = std::chrono::steady_clock::time_point(); + } + + // Send socket_->async_send( - boost::asio::buffer(*_buffer), + boost::asio::buffer(*_entry.first), std::bind( &udp_client_endpoint_base_impl::send_cbk, shared_from_this(), std::placeholders::_1, std::placeholders::_2, - _buffer + _entry.first ) ); } @@ -342,9 +363,9 @@ void udp_client_endpoint_impl::receive_cbk( // ensure to send back a message w/ wrong protocol version its_host->on_message(&(*_recv_buffer)[i], VSOMEIP_SOMEIP_HEADER_SIZE + 8, this, - boost::asio::ip::address(), + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } else if (!utility::is_valid_message_type(tp::tp::tp_flag_unset( @@ -371,17 +392,19 @@ void udp_client_endpoint_impl::receive_cbk( if (res.first) { its_host->on_message(&res.second[0], static_cast(res.second.size()), - this, boost::asio::ip::address(), + this, + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } } else { its_host->on_message(&(*_recv_buffer)[i], current_message_size, - this, boost::asio::ip::address(), + this, + false, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, remote_address_, remote_port_); } @@ -412,8 +435,7 @@ void udp_client_endpoint_impl::receive_cbk( } } -const std::string udp_client_endpoint_impl::get_address_port_remote() const { - boost::system::error_code ec; +std::string udp_client_endpoint_impl::get_address_port_remote() const { std::string its_address_port; its_address_port.reserve(21); boost::asio::ip::address its_address; @@ -425,7 +447,7 @@ const std::string udp_client_endpoint_impl::get_address_port_remote() const { return its_address_port; } -const std::string udp_client_endpoint_impl::get_address_port_local() const { +std::string udp_client_endpoint_impl::get_address_port_local() const { std::string its_address_port; its_address_port.reserve(21); boost::system::error_code ec; @@ -466,17 +488,21 @@ std::string udp_client_endpoint_impl::get_remote_information() const { + std::to_string(remote_.port()); } -void udp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, std::size_t _bytes, - const message_buffer_ptr_t &_sent_msg) { +void udp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, + std::size_t _bytes, const message_buffer_ptr_t &_sent_msg) { (void)_bytes; if (!_error) { std::lock_guard its_lock(mutex_); if (queue_.size() > 0) { - queue_size_ -= queue_.front()->size(); + queue_size_ -= queue_.front().first->size(); queue_.pop_front(); - auto its_buffer = get_front(); - if (its_buffer) - send_queued(its_buffer); + + update_last_departure(); + + auto its_entry = get_front(); + if (its_entry.first) { + send_queued(its_entry); + } } } else if (_error == boost::asio::error::broken_pipe) { state_ = cei_state_e::CLOSED; @@ -594,10 +620,12 @@ void udp_client_endpoint_impl::send_cbk(boost::system::error_code const &_error, } } -bool udp_client_endpoint_impl::tp_segmentation_enabled(service_t _service, - method_t _method) const { - return configuration_->tp_segment_messages_client_to_service(_service, - remote_address_.to_string(), remote_port_, _method); +bool udp_client_endpoint_impl::tp_segmentation_enabled( + service_t _service, method_t _method) const { + + return configuration_->is_tp_client(_service, + remote_address_.to_string(), remote_port_, + _method); } bool udp_client_endpoint_impl::is_reliable() const { diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp index bd44b48..79dee1c 100644 --- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp @@ -1,12 +1,17 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include #include +#include #include +#if VSOMEIP_BOOST_VERSION >= 106600 +#include +#include +#endif #include #include @@ -14,8 +19,9 @@ #include "../include/endpoint_definition.hpp" #include "../include/endpoint_host.hpp" #include "../include/tp.hpp" -#include "../../routing/include/routing_host.hpp" #include "../include/udp_server_endpoint_impl.hpp" +#include "../include/udp_server_endpoint_impl_receive_op.hpp" +#include "../../routing/include/routing_host.hpp" #include "../../configuration/include/configuration.hpp" #include "../../utility/include/byteorder.hpp" #include "../../utility/include/utility.hpp" @@ -29,16 +35,24 @@ udp_server_endpoint_impl::udp_server_endpoint_impl( const std::shared_ptr& _endpoint_host, const std::shared_ptr& _routing_host, const endpoint_type& _local, - boost::asio::io_service &_io, + boost::asio::io_context &_io, const std::shared_ptr& _configuration) : - server_endpoint_impl(_endpoint_host, _routing_host, _local, - _io, VSOMEIP_MAX_UDP_MESSAGE_SIZE, - _configuration->get_endpoint_queue_limit(_configuration->get_unicast_address().to_string(), _local.port()), - _configuration), +#if VSOMEIP_BOOST_VERSION >= 106600 + server_endpoint_impl( +#else + server_endpoint_impl( +#endif + _endpoint_host, _routing_host, _local, + _io, VSOMEIP_MAX_UDP_MESSAGE_SIZE, + _configuration->get_endpoint_queue_limit(_configuration->get_unicast_address().to_string(), _local.port()), + _configuration), unicast_socket_(_io, _local.protocol()), unicast_recv_buffer_(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0), + is_v4_(false), multicast_id_(0), joined_group_(false), + netmask_(_configuration->get_netmask()), + prefix_(_configuration->get_prefix()), local_port_(_local.port()), tp_reassembler_(std::make_shared(_configuration->get_max_message_size_unreliable(), _io)), tp_cleanup_timer_(_io) { @@ -48,9 +62,11 @@ udp_server_endpoint_impl::udp_server_endpoint_impl( boost::asio::socket_base::reuse_address optionReuseAddress(true); unicast_socket_.set_option(optionReuseAddress, ec); - boost::asio::detail::throw_error(ec, "reuse address"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": set reuse address option failed (" << ec.message() << ")"; -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) // If specified, bind to device std::string its_device(configuration_->get_device()); if (its_device != "") { @@ -62,27 +78,37 @@ udp_server_endpoint_impl::udp_server_endpoint_impl( #endif unicast_socket_.bind(_local, ec); - boost::asio::detail::throw_error(ec, "bind"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": bind failed (" << ec.message() << ")"; if (local_.address().is_v4()) { + is_v4_ = true; boost::asio::ip::multicast::outbound_interface option(_local.address().to_v4()); unicast_socket_.set_option(option, ec); - boost::asio::detail::throw_error(ec, "outbound interface option IPv4"); - } else if (local_.address().is_v6()) { + if (ec) + VSOMEIP_ERROR << __func__ + << ": set IPv4 outbound interface option failed (" << ec.message() << ")"; + } else { boost::asio::ip::multicast::outbound_interface option( static_cast(local_.address().to_v6().scope_id())); unicast_socket_.set_option(option, ec); - boost::asio::detail::throw_error(ec, "outbound interface option IPv6"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": set IPv6 outbound interface option failed (" << ec.message() << ")"; } boost::asio::socket_base::broadcast option(true); unicast_socket_.set_option(option, ec); - boost::asio::detail::throw_error(ec, "broadcast option"); + if (ec) + VSOMEIP_ERROR << __func__ + << ": set broadcast option failed (" << ec.message() << ")"; const int its_udp_recv_buffer_size = configuration_->get_udp_receive_buffer_size(); unicast_socket_.set_option(boost::asio::socket_base::receive_buffer_size( its_udp_recv_buffer_size), ec); + if (ec) { VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't set " << "SO_RCVBUF: " << ec.message() << " to: " << std::dec @@ -118,17 +144,6 @@ udp_server_endpoint_impl::udp_server_endpoint_impl( << " (" << its_udp_recv_buffer_size << ") local port:" << std::dec << local_port_; } - - -#ifdef _WIN32 - const char* optval("0001"); - ::setsockopt(unicast_socket_.native_handle(), IPPROTO_IP, IP_PKTINFO, - optval, sizeof(optval)); -#else - int optval(1); - ::setsockopt(unicast_socket_.native_handle(), IPPROTO_IP, IP_PKTINFO, - &optval, sizeof(optval)); -#endif } udp_server_endpoint_impl::~udp_server_endpoint_impl() { @@ -175,7 +190,7 @@ void udp_server_endpoint_impl::receive_unicast() { std::lock_guard its_lock(unicast_mutex_); - if(unicast_socket_.is_open()) { + if (unicast_socket_.is_open()) { unicast_socket_.async_receive_from( boost::asio::buffer(&unicast_recv_buffer_[0], max_message_size_), unicast_remote_, @@ -184,8 +199,7 @@ void udp_server_endpoint_impl::receive_unicast() { std::dynamic_pointer_cast< udp_server_endpoint_impl >(shared_from_this()), std::placeholders::_1, - std::placeholders::_2, - std::placeholders::_3 + std::placeholders::_2 ) ); } @@ -197,8 +211,9 @@ void udp_server_endpoint_impl::receive_unicast() { void udp_server_endpoint_impl::receive_multicast(uint8_t _multicast_id) { if (_multicast_id == multicast_id_ && multicast_socket_ && multicast_socket_->is_open()) { - multicast_socket_->async_receive_from( - boost::asio::buffer(&multicast_recv_buffer_[0], max_message_size_), +#if VSOMEIP_BOOST_VERSION >= 106600 + udp_server_endpoint_impl_receive_op its_operation { + *multicast_socket_, multicast_remote_, std::bind( &udp_server_endpoint_impl::on_multicast_received, @@ -207,9 +222,31 @@ void udp_server_endpoint_impl::receive_multicast(uint8_t _multicast_id) { std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, - _multicast_id + std::placeholders::_4 + ), + &multicast_recv_buffer_[0], + max_message_size_, + _multicast_id, + is_v4_, + boost::asio::ip::address(), + std::numeric_limits::min() + }; + multicast_socket_->async_wait(socket_type::wait_read, its_operation); +#else + multicast_socket_->async_receive_from( + boost::asio::buffer(&multicast_recv_buffer_[0], max_message_size_), + multicast_remote_, + std::bind( + &udp_server_endpoint_impl::on_multicast_received, + std::dynamic_pointer_cast< + udp_server_endpoint_impl >(shared_from_this()), + std::placeholders::_1, + std::placeholders::_2, + _multicast_id, + std::placeholders::_3 ) ); +#endif } } @@ -229,50 +266,68 @@ bool udp_server_endpoint_impl::send_error( bool ret(false); std::lock_guard its_lock(mutex_); const endpoint_type its_target(_target->get_address(), _target->get_port()); - const queue_iterator_type target_queue_iterator(find_or_create_queue_unlocked(its_target)); - auto& its_qpair = target_queue_iterator->second; - const bool queue_size_zero_on_entry(its_qpair.second.empty()); + const auto its_target_iterator(find_or_create_target_unlocked(its_target)); + auto& its_data = its_target_iterator->second; + const bool queue_size_zero_on_entry(its_data.queue_.empty()); if (check_message_size(nullptr, _size, its_target) == endpoint_impl::cms_ret_e::MSG_OK && - check_queue_limit(_data, _size, its_qpair.first)) { - its_qpair.second.emplace_back( - std::make_shared(_data, _data + _size)); - its_qpair.first += _size; + check_queue_limit(_data, _size, its_data.queue_size_)) { + its_data.queue_.emplace_back( + std::make_pair(std::make_shared(_data, _data + _size), 0)); + its_data.queue_size_ += _size; if (queue_size_zero_on_entry) { // no writing in progress - send_queued(target_queue_iterator); + (void)send_queued(its_target_iterator); } ret = true; } return ret; } -void udp_server_endpoint_impl::send_queued( - const queue_iterator_type _queue_iterator) { +bool udp_server_endpoint_impl::send_queued( + const target_data_iterator_type _it) { - message_buffer_ptr_t its_buffer = _queue_iterator->second.second.front(); + static std::chrono::steady_clock::time_point its_last_sent; + const auto its_entry = _it->second.queue_.front(); #if 0 - std::stringstream msg; - msg << "usei::sq(" << _queue_iterator->first.address().to_string() << ":" - << _queue_iterator->first.port() << "): "; - for (std::size_t i = 0; i < its_buffer->size(); ++i) - msg << std::hex << std::setw(2) << std::setfill('0') - << (int)(*its_buffer)[i] << " "; - VSOMEIP_INFO << msg.str(); + std::stringstream msg; + msg << "usei::sq(" << _queue_iterator->first.address().to_string() << ":" + << _queue_iterator->first.port() << "): "; + for (std::size_t i = 0; i < its_buffer->size(); ++i) + msg << std::hex << std::setw(2) << std::setfill('0') + << (int)(*its_entry.first)[i] << " "; + VSOMEIP_INFO << msg.str(); #endif std::lock_guard its_lock(unicast_mutex_); + // Check whether we need to wait (SOME/IP-TP separation time) + if (its_entry.second > 0) { + if (its_last_sent != std::chrono::steady_clock::time_point()) { + const auto its_elapsed + = std::chrono::duration_cast( + std::chrono::steady_clock::now() - its_last_sent).count(); + if (its_entry.second > its_elapsed) + std::this_thread::sleep_for( + std::chrono::microseconds(its_entry.second - its_elapsed)); + } + its_last_sent = std::chrono::steady_clock::now(); + } else { + its_last_sent = std::chrono::steady_clock::time_point(); + } + unicast_socket_.async_send_to( - boost::asio::buffer(*its_buffer), - _queue_iterator->first, + boost::asio::buffer(*its_entry.first), + _it->first, std::bind( &udp_server_endpoint_base_impl::send_cbk, shared_from_this(), - _queue_iterator, + _it, std::placeholders::_1, std::placeholders::_2 ) ); + + return false; } void udp_server_endpoint_impl::get_configured_times_from_endpoint( @@ -325,126 +380,18 @@ void udp_server_endpoint_impl::join_unlocked(const std::string &_address) { VSOMEIP_DEBUG << "Joining to multicast group " << _address << " from " << local_.address().to_string(); - boost::system::error_code ec; - - bool is_v4(false); - bool is_v6(false); - { - std::lock_guard its_lock(local_mutex_); - is_v4 = local_.address().is_v4(); - is_v6 = local_.address().is_v6(); - } - - if (multicast_recv_buffer_.empty()) - multicast_recv_buffer_.resize(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0); - - if (!multicast_local_) { - if (is_v4) { - multicast_local_ = std::unique_ptr( - new endpoint_type(boost::asio::ip::address_v4::any(), local_port_)); - } - if (is_v6) { - multicast_local_ = std::unique_ptr( - new endpoint_type(boost::asio::ip::address_v6::any(), local_port_)); - } - } - - if (!multicast_socket_) { - multicast_socket_ = std::unique_ptr( - new socket_type(service_, local_.protocol())); - - boost::asio::socket_base::reuse_address optionReuseAddress(true); - multicast_socket_->set_option(optionReuseAddress, ec); - boost::asio::detail::throw_error(ec, "reuse address in multicast"); - boost::asio::socket_base::broadcast optionBroadcast(true); - multicast_socket_->set_option(optionBroadcast, ec); - boost::asio::detail::throw_error(ec, "set broadcast option"); - - multicast_socket_->bind(*multicast_local_, ec); - boost::asio::detail::throw_error(ec, "bind multicast"); - - const int its_udp_recv_buffer_size = - configuration_->get_udp_receive_buffer_size(); - multicast_socket_->set_option(boost::asio::socket_base::receive_buffer_size( - its_udp_recv_buffer_size), ec); - if (ec) { - VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't set " - << "SO_RCVBUF: " << ec.message() << " to: " << std::dec - << its_udp_recv_buffer_size << " local port: " << std::dec - << local_port_; - } - - boost::asio::socket_base::receive_buffer_size its_option; - multicast_socket_->get_option(its_option, ec); - #ifdef __linux__ - // If regular setting of the buffer size did not work, try to force - // (requires CAP_NET_ADMIN to be successful) - if (its_option.value() < 0 - || its_option.value() < its_udp_recv_buffer_size) { - ec.assign(setsockopt(multicast_socket_->native_handle(), - SOL_SOCKET, SO_RCVBUFFORCE, - &its_udp_recv_buffer_size, sizeof(its_udp_recv_buffer_size)), - boost::system::generic_category()); - if (!ec) { - VSOMEIP_INFO << "udp_server_endpoint_impl: " - << "SO_RCVBUFFORCE: successful."; - } - multicast_socket_->get_option(its_option, ec); - } - #endif - if (ec) { - VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't get " - << "SO_RCVBUF: " << ec.message() << " local port:" - << std::dec << local_port_; - } else { - VSOMEIP_INFO << "udp_server_endpoint_impl: SO_RCVBUF is: " - << std::dec << its_option.value() - << " (" << its_udp_recv_buffer_size << ") local port:" - << std::dec << local_port_; - } - -#ifdef _WIN32 - const char* optval("0001"); - if (is_v4) { - ::setsockopt(multicast_socket_->native_handle(), IPPROTO_IP, IP_PKTINFO, - optval, sizeof(optval)); - } else if (is_v6) { - ::setsockopt(multicast_socket_->native_handle(), IPPROTO_IPV6, IPV6_PKTINFO, - optval, sizeof(optval)); - } + auto its_endpoint_host = endpoint_host_.lock(); + if (its_endpoint_host) { + multicast_option_t its_join_option { shared_from_this(), true, +#if VSOMEIP_BOOST_VERSION < 106600 + boost::asio::ip::address::from_string(_address) }; #else - int optval(1); - if (is_v4) { - ::setsockopt(multicast_socket_->native_handle(), IPPROTO_IP, IP_PKTINFO, - &optval, sizeof(optval)); - } else { - ::setsockopt(multicast_socket_->native_handle(), IPPROTO_IPV6, IPV6_RECVPKTINFO, - &optval, sizeof(optval)); - } + boost::asio::ip::make_address(_address) }; #endif - multicast_id_++; - receive_multicast(multicast_id_); - } - - if (is_v4) { - multicast_socket_->set_option(ip::udp_ext::socket::reuse_address(true)); - multicast_socket_->set_option( - boost::asio::ip::multicast::enable_loopback(false)); - multicast_socket_->set_option(boost::asio::ip::multicast::join_group( - boost::asio::ip::address::from_string(_address).to_v4(), - local_.address().to_v4())); - } else if (is_v6) { - multicast_socket_->set_option(ip::udp_ext::socket::reuse_address(true)); - multicast_socket_->set_option( - boost::asio::ip::multicast::enable_loopback(false)); - multicast_socket_->set_option(boost::asio::ip::multicast::join_group( - boost::asio::ip::address::from_string(_address).to_v6(), - local_.address().to_v6().scope_id())); + its_endpoint_host->add_multicast_option(its_join_option); } joined_[_address] = false; - joined_group_ = true; - } catch (const std::exception &e) { VSOMEIP_ERROR << "udp_server_endpoint_impl::join" << ":" << e.what() << " address: " << _address; @@ -473,31 +420,20 @@ void udp_server_endpoint_impl::leave_unlocked(const std::string &_address) { VSOMEIP_DEBUG << "Leaving the multicast group " << _address << " from " << local_.address().to_string(); - bool is_v4(false); - bool is_v6(false); - { - std::lock_guard its_lock(local_mutex_); - is_v4 = local_.address().is_v4(); - is_v6 = local_.address().is_v6(); - } - if (is_v4) { - multicast_socket_->set_option(boost::asio::ip::multicast::leave_group( - boost::asio::ip::address::from_string(_address))); - } else if (is_v6) { - multicast_socket_->set_option(boost::asio::ip::multicast::leave_group( - boost::asio::ip::address::from_string(_address))); + if (multicast_socket_) { + auto its_endpoint_host = endpoint_host_.lock(); + if (its_endpoint_host) { + multicast_option_t its_leave_option { shared_from_this(), +#if VSOMEIP_BOOST_VERSION < 106600 + false, boost::asio::ip::address::from_string(_address) }; +#else + false, boost::asio::ip::make_address(_address) }; +#endif + its_endpoint_host->add_multicast_option(its_leave_option); + } } joined_.erase(_address); - if (0 == joined_.size()) { - joined_group_ = false; - - boost::system::error_code ec; - multicast_socket_->cancel(ec); - - multicast_socket_.reset(nullptr); - multicast_local_.reset(nullptr); - } } } catch (const std::exception &e) { @@ -541,8 +477,7 @@ void udp_server_endpoint_impl::set_local_port(std::uint16_t _port) { void udp_server_endpoint_impl::on_unicast_received( boost::system::error_code const &_error, - std::size_t _bytes, - boost::asio::ip::address const &_destination) { + std::size_t _bytes) { if (_error != boost::asio::error::operation_aborted) { { @@ -550,7 +485,7 @@ void udp_server_endpoint_impl::on_unicast_received( // & multicast messages are not processed in parallel. This aligns // the behavior of endpoints with one and two active sockets. std::lock_guard its_lock(multicast_mutex_); - on_message_received(_error, _bytes, _destination, + on_message_received(_error, _bytes, false, unicast_remote_, unicast_recv_buffer_); } receive_unicast(); @@ -560,14 +495,20 @@ void udp_server_endpoint_impl::on_unicast_received( void udp_server_endpoint_impl::on_multicast_received( boost::system::error_code const &_error, std::size_t _bytes, - boost::asio::ip::address const &_destination, - uint8_t _multicast_id) { + uint8_t _multicast_id, + const boost::asio::ip::address &_destination) { std::lock_guard its_lock(multicast_mutex_); if (_error != boost::asio::error::operation_aborted) { // Filter messages sent from the same source address - if (multicast_remote_.address() != local_.address()) { - on_message_received(_error, _bytes, _destination, + if (multicast_remote_.address() != local_.address() + && is_same_subnet(multicast_remote_.address())) { + + auto find_joined = joined_.find(_destination.to_string()); + if (find_joined != joined_.end()) + find_joined->second = true; + + on_message_received(_error, _bytes, true, multicast_remote_, multicast_recv_buffer_); } @@ -577,7 +518,7 @@ void udp_server_endpoint_impl::on_multicast_received( void udp_server_endpoint_impl::on_message_received( boost::system::error_code const &_error, std::size_t _bytes, - boost::asio::ip::address const &_destination, + bool _is_multicast, endpoint_type const &_remote, message_buffer_t const &_buffer) { #if 0 @@ -585,7 +526,7 @@ void udp_server_endpoint_impl::on_message_received( msg << "usei::rcb(" << _error.message() << "): "; for (std::size_t i = 0; i < _bytes; ++i) msg << std::hex << std::setw(2) << std::setfill('0') - << (int) recv_buffer_[i] << " "; + << (int) _buffer[i] << " "; VSOMEIP_INFO << msg.str(); #endif std::shared_ptr its_host = routing_host_.lock(); @@ -613,7 +554,7 @@ void udp_server_endpoint_impl::on_message_received( } else if (current_message_size > VSOMEIP_RETURN_CODE_POS && (_buffer[i + VSOMEIP_PROTOCOL_VERSION_POS] != VSOMEIP_PROTOCOL_VERSION || !utility::is_valid_message_type(tp::tp::tp_flag_unset(_buffer[i + VSOMEIP_MESSAGE_TYPE_POS])) || - /*!utility::is_valid_return_code(static_cast(_buffer[i + VSOMEIP_RETURN_CODE_POS])) ||*/ + !utility::is_valid_return_code(static_cast(_buffer[i + VSOMEIP_RETURN_CODE_POS])) || (tp::tp::tp_flag_is_set(_buffer[i + VSOMEIP_MESSAGE_TYPE_POS]) && get_local_port() == configuration_->get_sd_port()) )) { if (_buffer[i + VSOMEIP_PROTOCOL_VERSION_POS] != VSOMEIP_PROTOCOL_VERSION) { @@ -625,9 +566,9 @@ void udp_server_endpoint_impl::on_message_received( // ensure to send back a message w/ wrong protocol version its_host->on_message(&_buffer[i], VSOMEIP_SOMEIP_HEADER_SIZE + 8, this, - _destination, + _is_multicast, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, its_remote_address, its_remote_port); } else if (!utility::is_valid_message_type(tp::tp::tp_flag_unset( _buffer[i + VSOMEIP_MESSAGE_TYPE_POS]))) { @@ -663,21 +604,9 @@ void udp_server_endpoint_impl::on_message_received( const session_t its_session = VSOMEIP_BYTES_TO_WORD( _buffer[i + VSOMEIP_SESSION_POS_MIN], _buffer[i + VSOMEIP_SESSION_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - _buffer[i + VSOMEIP_METHOD_POS_MIN], - _buffer[i + VSOMEIP_METHOD_POS_MAX]); - - std::lock_guard its_requests_guard(requests_mutex_); - requests_[its_client] - [std::make_tuple(its_service, its_method, its_session)] = _remote; - } - } else if (its_service != VSOMEIP_SD_SERVICE - && utility::is_notification(_buffer[i + VSOMEIP_MESSAGE_TYPE_POS]) - && joined_group_) { - boost::system::error_code ec; - const auto found_address = joined_.find(_destination.to_string(ec)); - if (found_address != joined_.end()) { - found_address->second = true; + clients_mutex_.lock(); + clients_[its_client][its_session] = _remote; + clients_mutex_.unlock(); } } if (tp::tp::tp_flag_is_set(_buffer[i + VSOMEIP_MESSAGE_TYPE_POS])) { @@ -699,33 +628,17 @@ void udp_server_endpoint_impl::on_message_received( res.second[VSOMEIP_CLIENT_POS_MIN], res.second[VSOMEIP_CLIENT_POS_MAX]); if (its_client != MAGIC_COOKIE_CLIENT) { - const service_t its_service = VSOMEIP_BYTES_TO_WORD( - res.second[VSOMEIP_SERVICE_POS_MIN], - res.second[VSOMEIP_SERVICE_POS_MAX]); - const method_t its_method = VSOMEIP_BYTES_TO_WORD( - res.second[VSOMEIP_METHOD_POS_MIN], - res.second[VSOMEIP_METHOD_POS_MAX]); const session_t its_session = VSOMEIP_BYTES_TO_WORD( res.second[VSOMEIP_SESSION_POS_MIN], res.second[VSOMEIP_SESSION_POS_MAX]); - - std::lock_guard its_requests_guard(requests_mutex_); - requests_[its_client] - [std::make_tuple(its_service, its_method, its_session)] = _remote; - } - } else if (its_service != VSOMEIP_SD_SERVICE - && utility::is_notification(res.second[VSOMEIP_MESSAGE_TYPE_POS]) - && joined_group_) { - boost::system::error_code ec; - const auto found_address = joined_.find(_destination.to_string(ec)); - if (found_address != joined_.end()) { - found_address->second = true; + std::lock_guard its_client_lock(clients_mutex_); + clients_[its_client][its_session] = _remote; } } its_host->on_message(&res.second[0], static_cast(res.second.size()), - this, _destination, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + this, _is_multicast, VSOMEIP_ROUTING_CLIENT, + nullptr, its_remote_address, its_remote_port); } } else { @@ -733,9 +646,9 @@ void udp_server_endpoint_impl::on_message_received( (current_message_size > VSOMEIP_SOMEIP_HEADER_SIZE && current_message_size >= remaining_bytes)) { its_host->on_message(&_buffer[i], - current_message_size, this, _destination, + current_message_size, this, _is_multicast, VSOMEIP_ROUTING_CLIENT, - std::make_pair(ANY_UID, ANY_GID), + nullptr, its_remote_address, its_remote_port); } else { //ignore messages for service discovery with shorter SomeIP length @@ -772,21 +685,63 @@ void udp_server_endpoint_impl::on_message_received( } } +bool udp_server_endpoint_impl::is_same_subnet(const boost::asio::ip::address &_address) const { + + bool is_same(true); +#if VSOMEIP_BOOST_VERSION < 106600 + // TODO: This needs some (more) testing + if (_address.is_v4()) { + uint32_t its_local(uint32_t(local_.address().to_v4().to_ulong())); + uint32_t its_mask(uint32_t(netmask_.to_v4().to_ulong())); + uint32_t its_address(uint32_t(_address.to_v4().to_ulong())); + + return ((its_local & its_mask) == (its_address & its_mask)); + } else { + boost::asio::ip::address_v6::bytes_type its_local(local_.address().to_v6().to_bytes()); + boost::asio::ip::address_v6::bytes_type its_address(_address.to_v6().to_bytes()); + + for (size_t i = 0; i < its_local.size(); ++i) { + byte_t its_mask(0x00); + if ((i+1) * sizeof(byte_t) <= prefix_) + its_mask = 0xff; + else if (i <= prefix_) + its_mask = byte_t(0xff << (((i+1) * sizeof(byte_t)) - prefix_)); + + if ((its_local[i] & its_mask) != (its_address[i] & its_mask)) + return (false); + } + + return (true); + } +#else + if (_address.is_v4()) { + boost::asio::ip::network_v4 its_network(local_.address().to_v4(), netmask_.to_v4()); + boost::asio::ip::address_v4_range its_hosts = its_network.hosts(); + is_same = (its_hosts.find(_address.to_v4()) != its_hosts.end()); + } else { + boost::asio::ip::network_v6 its_network(local_.address().to_v6(), prefix_); + boost::asio::ip::address_v6_range its_hosts = its_network.hosts(); + is_same = (its_hosts.find(_address.to_v6()) != its_hosts.end()); + } +#endif + return (is_same); +} + void udp_server_endpoint_impl::print_status() { std::lock_guard its_lock(mutex_); VSOMEIP_INFO << "status use: " << std::dec << local_port_ - << " number queues: " << std::dec << queues_.size() + << " number targets: " << std::dec << targets_.size() << " recv_buffer: " << std::dec << unicast_recv_buffer_.capacity() << " multicast_recv_buffer: " << std::dec << multicast_recv_buffer_.capacity(); - for (const auto &c : queues_) { + for (const auto &c : targets_) { std::size_t its_data_size(0); std::size_t its_queue_size(0); - its_queue_size = c.second.second.size(); - its_data_size = c.second.first; + its_queue_size = c.second.queue_.size(); + its_data_size = c.second.queue_size_; boost::system::error_code ec; VSOMEIP_INFO << "status use: client: " @@ -798,14 +753,16 @@ void udp_server_endpoint_impl::print_status() { } std::string udp_server_endpoint_impl::get_remote_information( - const queue_iterator_type _queue_iterator) const { + const target_data_iterator_type _it) const { + boost::system::error_code ec; - return _queue_iterator->first.address().to_string(ec) + ":" - + std::to_string(_queue_iterator->first.port()); + return _it->first.address().to_string(ec) + ":" + + std::to_string(_it->first.port()); } std::string udp_server_endpoint_impl::get_remote_information( const endpoint_type& _remote) const { + boost::system::error_code ec; return _remote.address().to_string(ec) + ":" + std::to_string(_remote.port()); @@ -815,7 +772,7 @@ bool udp_server_endpoint_impl::is_reliable() const { return false; } -const std::string udp_server_endpoint_impl::get_address_port_local() const { +std::string udp_server_endpoint_impl::get_address_port_local() const { std::lock_guard its_lock(unicast_mutex_); std::string its_address_port; @@ -835,9 +792,171 @@ const std::string udp_server_endpoint_impl::get_address_port_local() const { bool udp_server_endpoint_impl::tp_segmentation_enabled( service_t _service, method_t _method) const { - return configuration_->tp_segment_messages_service_to_client(_service, - local_.address().to_string(), - local_.port(), _method); + return configuration_->is_tp_service(_service, + local_.address().to_string(), local_.port(), + _method); +} + +void +udp_server_endpoint_impl::set_multicast_option( + const boost::asio::ip::address &_address, bool _is_join) { + + boost::system::error_code ec; + + if (_is_join) { + if (!multicast_socket_) { + std::lock_guard its_guard(multicast_mutex_); + + multicast_socket_ = std::unique_ptr( + new socket_type(io_, local_.protocol())); + + multicast_socket_->set_option(ip::udp::socket::reuse_address(true), ec); + if (ec) + VSOMEIP_ERROR << __func__ + << ": set reuse address option failed (" << ec.message() << ")"; + +#ifdef _WIN32 + const char *its_option("0001"); + ::setsockopt(multicast_socket_->native_handle(), + (is_v4_ ? IPPROTO_IP : IPPROTO_IPV6), + (is_v4_ ? IP_PKTINFO : IPV6_PKTINFO), + its_option, sizeof(its_option)); +#else + int its_pktinfo_option(1); + ::setsockopt(multicast_socket_->native_handle(), + (is_v4_ ? IPPROTO_IP : IPPROTO_IPV6), + (is_v4_ ? IP_PKTINFO : IPV6_PKTINFO), + &its_pktinfo_option, sizeof(its_pktinfo_option)); +#endif + + if (multicast_recv_buffer_.empty()) + multicast_recv_buffer_.resize(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0); + + if (!multicast_local_) { + if (is_v4_) { + multicast_local_ = std::unique_ptr( + new endpoint_type(boost::asio::ip::address_v4::any(), local_port_)); + } else { // is_v6 + multicast_local_ = std::unique_ptr( + new endpoint_type(boost::asio::ip::address_v6::any(), local_port_)); + } + } + + multicast_socket_->bind(*multicast_local_, ec); + if (ec) + VSOMEIP_ERROR << __func__ + << ": bind failed (" << ec.message() << ")"; + + const int its_udp_recv_buffer_size = + configuration_->get_udp_receive_buffer_size(); + + multicast_socket_->set_option(boost::asio::socket_base::receive_buffer_size( + its_udp_recv_buffer_size), ec); + +#ifndef _WIN32 + // define socket timeout + struct timeval timeout; + timeout.tv_sec = 0; + timeout.tv_usec = VSOMEIP_SETSOCKOPT_TIMEOUT_US; + + if (setsockopt( + multicast_socket_->native_handle(), + SOL_SOCKET, SO_RCVTIMEO, + &timeout, sizeof(timeout)) == -1) { + VSOMEIP_WARNING << __func__ + << ": unable to setsockopt SO_RCVTIMEO"; + } + + if (setsockopt( + multicast_socket_->native_handle(), + SOL_SOCKET, SO_SNDTIMEO, + &timeout, sizeof(timeout)) == -1) { + VSOMEIP_WARNING << __func__ + << ": unable to setsockopt SO_SNDTIMEO"; + } +#endif + + if (ec) { + VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't set " + << "SO_RCVBUF: " << ec.message() << " to: " << std::dec + << its_udp_recv_buffer_size << " local port: " << std::dec + << local_port_; + } + + boost::asio::socket_base::receive_buffer_size its_option; + multicast_socket_->get_option(its_option, ec); +#ifdef __linux__ + // If regular setting of the buffer size did not work, try to force + // (requires CAP_NET_ADMIN to be successful) + if (its_option.value() < 0 + || its_option.value() < its_udp_recv_buffer_size) { + ec.assign(setsockopt(multicast_socket_->native_handle(), + SOL_SOCKET, SO_RCVBUFFORCE, + &its_udp_recv_buffer_size, sizeof(its_udp_recv_buffer_size)), + boost::system::generic_category()); + if (!ec) { + VSOMEIP_INFO << "udp_server_endpoint_impl: " + << "SO_RCVBUFFORCE: successful."; + } + multicast_socket_->get_option(its_option, ec); + } +#endif + if (ec) { + VSOMEIP_WARNING << "udp_server_endpoint_impl: couldn't get " + << "SO_RCVBUF: " << ec.message() << " local port:" + << std::dec << local_port_; + } else { + VSOMEIP_INFO << "udp_server_endpoint_impl: SO_RCVBUF is: " + << std::dec << its_option.value() + << " (" << its_udp_recv_buffer_size << ") local port:" + << std::dec << local_port_; + } + + multicast_id_++; + receive_multicast(multicast_id_); + } + + boost::asio::ip::multicast::join_group its_join_option; + { + std::lock_guard its_lock(local_mutex_); + if (is_v4_) { + + its_join_option = boost::asio::ip::multicast::join_group( + _address.to_v4(), + local_.address().to_v4()); + } else { + its_join_option = boost::asio::ip::multicast::join_group( + _address.to_v6(), + static_cast(local_.address().to_v6().scope_id())); + } + } + multicast_socket_->set_option(its_join_option, ec); + + if (!ec) { + std::lock_guard its_guard(multicast_mutex_); + joined_[_address.to_string()] = false; + joined_group_ = true; + } + } else { + if (multicast_socket_) { + boost::asio::ip::multicast::leave_group its_leave_option(_address); + multicast_socket_->set_option(its_leave_option, ec); + + if (!ec) { + std::lock_guard its_guard(multicast_mutex_); + joined_.erase(_address.to_string()); + + if (0 == joined_.size()) { + joined_group_ = false; + + multicast_socket_->cancel(ec); + + multicast_socket_.reset(nullptr); + multicast_local_.reset(nullptr); + } + } + } + } } } // namespace vsomeip_v3 diff --git a/implementation/endpoints/src/virtual_server_endpoint_impl.cpp b/implementation/endpoints/src/virtual_server_endpoint_impl.cpp index 5c8981c..e4441a9 100644 --- a/implementation/endpoints/src/virtual_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/virtual_server_endpoint_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,9 +12,9 @@ namespace vsomeip_v3 { virtual_server_endpoint_impl::virtual_server_endpoint_impl( const std::string &_address, uint16_t _port, bool _reliable, - boost::asio::io_service& _service) + boost::asio::io_context &_io) : address_(_address), port_(_port), reliable_(_reliable), use_count_(0), - service_(_service) { + io_(_io) { } virtual_server_endpoint_impl::~virtual_server_endpoint_impl() { @@ -23,10 +23,10 @@ virtual_server_endpoint_impl::~virtual_server_endpoint_impl() { void virtual_server_endpoint_impl::start() { } -void virtual_server_endpoint_impl::prepare_stop(endpoint::prepare_stop_handler_t _handler, +void virtual_server_endpoint_impl::prepare_stop(const endpoint::prepare_stop_handler_t &_handler, service_t _service) { auto ptr = shared_from_this(); - service_.post([ptr, _handler, _service]() { + io_.post([ptr, _handler, _service]() { _handler(ptr, _service); }); } @@ -56,14 +56,6 @@ bool virtual_server_endpoint_impl::send(const byte_t *_data, uint32_t _size) { return false; } -bool virtual_server_endpoint_impl::send(const std::vector& _cmd_header, - const byte_t *_data, uint32_t _size) { - (void)_cmd_header; - (void)_data; - (void)_size; - return false; -} - bool virtual_server_endpoint_impl::send_to( const std::shared_ptr _target, const byte_t *_data, uint32_t _size) { @@ -147,7 +139,7 @@ void virtual_server_endpoint_impl::restart(bool _force) { } void virtual_server_endpoint_impl::register_error_handler( - error_handler_t _handler) { + const error_handler_t &_handler) { (void)_handler; } diff --git a/implementation/helper/1.55/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/1.55/boost/asio/basic_datagram_socket_ext.hpp deleted file mode 100644 index 43b2d93..0000000 --- a/implementation/helper/1.55/boost/asio/basic_datagram_socket_ext.hpp +++ /dev/null @@ -1,954 +0,0 @@ -// -// basic_datagram_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -/// Provides datagram-oriented socket functionality. -/** - * The basic_datagram_socket class template provides asynchronous and blocking - * datagram-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template > -class basic_datagram_socket_ext - : public basic_socket -{ -public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// socket. - typedef typename DatagramSocketService::native_handle_type native_type; - - /// The native representation of a socket. - typedef typename DatagramSocketService::native_handle_type native_handle_type; - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param io_service The io_service object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - */ - explicit basic_datagram_socket_ext(boost::asio::io_service& io_service) - : basic_socket(io_service) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param io_service The io_service object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(boost::asio::io_service& io_service, - const protocol_type& protocol) - : basic_socket(io_service, protocol) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param io_service The io_service object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(boost::asio::io_service& io_service, - const endpoint_type& endpoint) - : basic_socket(io_service, endpoint) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param io_service The io_service object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(boost::asio::io_service& io_service, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket( - io_service, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_datagram_socket from another. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_service&) constructor. - */ - basic_datagram_socket_ext(basic_datagram_socket_ext&& other) - : basic_socket( - BOOST_ASIO_MOVE_CAST(basic_datagram_socket_ext)(other)) - { - } - - /// Move-assign a basic_datagram_socket from another. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_service&) constructor. - */ - basic_datagram_socket_ext& operator=(basic_datagram_socket_ext&& other) - { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST(basic_datagram_socket_ext)(other)); - return *this; - } - - /// Move-construct a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_service&) constructor. - */ - template - basic_datagram_socket_ext( - basic_datagram_socket_ext&& other, - typename enable_if::value>::type* = 0) - : basic_socket( - BOOST_ASIO_MOVE_CAST2(basic_datagram_socket_ext< - Protocol1, DatagramSocketService1>)(other)) - { - } - - /// Move-assign a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_service&) constructor. - */ - template - typename enable_if::value, - basic_datagram_socket_ext>::type& operator=( - basic_datagram_socket_ext&& other) - { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST2(basic_datagram_socket_ext< - Protocol1, DatagramSocketService1>)(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code socket.send(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().send( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.send_to(boost::asio::buffer(data, size), destination); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send_to( - this->get_implementation(), buffers, destination, 0, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send_to( - this->get_implementation(), buffers, destination, flags, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->get_service().send_to(this->get_implementation(), - buffers, destination, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_send_to( - * boost::asio::buffer(data, size), destination, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, 0, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, flags, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.receive(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * boost::asio::ip::udp::endpoint sender_endpoint; - * socket.receive_from( - * boost::asio::buffer(data, size), sender_endpoint); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->get_service().receive_from(this->get_implementation(), - buffers, sender_endpoint, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.async_receive_from( - * boost::asio::buffer(data, size), sender_endpoint, handler); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP diff --git a/implementation/helper/1.55/boost/asio/basic_socket_acceptor_ext.hpp b/implementation/helper/1.55/boost/asio/basic_socket_acceptor_ext.hpp deleted file mode 100644 index 4af4bac..0000000 --- a/implementation/helper/1.55/boost/asio/basic_socket_acceptor_ext.hpp +++ /dev/null @@ -1,1139 +0,0 @@ -// -// basic_socket_acceptor_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -/// Provides the ability to accept new connections. -/** - * The basic_socket_acceptor_ext class template is used for accepting new socket - * connections. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Example - * Opening a socket acceptor with the SO_REUSEADDR option enabled: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); - * acceptor.open(endpoint.protocol()); - * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ -template > -class basic_socket_acceptor_ext - : public basic_io_object, - public socket_base -{ -public: - /// (Deprecated: Use native_handle_type.) The native representation of an - /// acceptor. - typedef typename SocketAcceptorService::native_handle_type native_type; - - /// The native representation of an acceptor. - typedef typename SocketAcceptorService::native_handle_type native_handle_type; - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param io_service The io_service object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - */ - explicit basic_socket_acceptor_ext(boost::asio::io_service& io_service) - : basic_io_object(io_service) - { - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param io_service The io_service object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(boost::asio::io_service& io_service, - const protocol_type& protocol) - : basic_io_object(io_service) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param io_service The io_service object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor_ext acceptor(io_service); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(listen_backlog); - * @endcode - */ - basic_socket_acceptor_ext(boost::asio::io_service& io_service, - const endpoint_type& endpoint, bool reuse_addr = true) - : basic_io_object(io_service) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - this->get_service().set_option(this->get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - this->get_service().listen(this->get_implementation(), - socket_base::max_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct a basic_socket_acceptor_ext on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param io_service The io_service object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(boost::asio::io_service& io_service, - const protocol_type& protocol, const native_handle_type& native_acceptor) - : basic_io_object(io_service) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket_acceptor_ext from another. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor_ext(io_service&) constructor. - */ - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other) - : basic_io_object( - BOOST_ASIO_MOVE_CAST(basic_socket_acceptor_ext)(other)) - { - } - - /// Move-assign a basic_socket_acceptor_ext from another. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor_ext(io_service&) constructor. - */ - basic_socket_acceptor_ext& operator=(basic_socket_acceptor_ext&& other) - { - basic_io_object::operator=( - BOOST_ASIO_MOVE_CAST(basic_socket_acceptor_ext)(other)); - return *this; - } - - // All socket acceptors have access to each other's implementations. - template - friend class basic_socket_acceptor_ext; - - /// Move-construct a basic_socket_acceptor_ext from an acceptor of another - /// protocol type. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. - */ - template - basic_socket_acceptor_ext( - basic_socket_acceptor_ext&& other, - typename enable_if::value>::type* = 0) - : basic_io_object(other.get_io_service()) - { - this->get_service().template converting_move_construct( - this->get_implementation(), other.get_implementation()); - } - - /// Move-assign a basic_socket_acceptor_ext from an acceptor of another protocol - /// type. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_service&) constructor. - */ - template - typename enable_if::value, - basic_socket_acceptor_ext>::type& operator=( - basic_socket_acceptor_ext&& other) - { - basic_socket_acceptor_ext tmp(BOOST_ASIO_MOVE_CAST2(basic_socket_acceptor_ext< - Protocol1, SocketAcceptorService1>)(other)); - basic_io_object::operator=( - BOOST_ASIO_MOVE_CAST(basic_socket_acceptor_ext)(tmp)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * acceptor.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * boost::system::error_code ec; - * acceptor.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - boost::system::error_code open(const protocol_type& protocol, - boost::system::error_code& ec) - { - return this->get_service().open(this->get_implementation(), protocol, ec); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_acceptor) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @param ec Set to indicate what error occurred, if any. - */ - boost::system::error_code assign(const protocol_type& protocol, - const native_handle_type& native_acceptor, boost::system::error_code& ec) - { - return this->get_service().assign(this->get_implementation(), - protocol, native_acceptor, ec); - } - - /// Determine whether the acceptor is open. - bool is_open() const - { - return this->get_service().is_open(this->get_implementation()); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * acceptor.bind(endpoint); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * boost::system::error_code ec; - * acceptor.bind(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - boost::system::error_code bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - return this->get_service().bind(this->get_implementation(), endpoint, ec); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @throws boost::system::system_error Thrown on failure. - */ - void listen(int backlog = socket_base::max_connections) - { - boost::system::error_code ec; - this->get_service().listen(this->get_implementation(), backlog, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::system::error_code ec; - * acceptor.listen(boost::asio::socket_base::max_connections, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - boost::system::error_code listen(int backlog, boost::system::error_code& ec) - { - return this->get_service().listen(this->get_implementation(), backlog, ec); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @throws boost::system::system_error Thrown on failure. - */ - void close() - { - boost::system::error_code ec; - this->get_service().close(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::system::error_code ec; - * acceptor.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - boost::system::error_code close(boost::system::error_code& ec) - { - return this->get_service().close(this->get_implementation(), ec); - } - - /// (Deprecated: Use native_handle().) Get the native acceptor representation. - /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. - */ - native_type native() - { - return this->get_service().native_handle(this->get_implementation()); - } - - /// Get the native acceptor representation. - /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return this->get_service().native_handle(this->get_implementation()); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - */ - void cancel() - { - boost::system::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - */ - boost::system::error_code cancel(boost::system::error_code& ec) - { - return this->get_service().cancel(this->get_implementation(), ec); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * acceptor.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * boost::system::error_code ec; - * acceptor.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - boost::system::error_code set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - return this->get_service().set_option( - this->get_implementation(), option, ec); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * acceptor.get_option(option); - * bool is_set = option.get(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) - { - boost::system::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * boost::system::error_code ec; - * acceptor.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.get(); - * @endcode - */ - template - boost::system::error_code get_option(GettableSocketOption& option, - boost::system::error_code& ec) - { - return this->get_service().get_option( - this->get_implementation(), option, ec); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * socket.io_control(command); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - this->get_service().io_control(this->get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - boost::system::error_code io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - return this->get_service().io_control( - this->get_implementation(), command, ec); - } - - /// Gets the non-blocking mode of the acceptor. - /** - * @returns @c true if the acceptor's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return this->get_service().non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().non_blocking(this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - boost::system::error_code non_blocking( - bool mode, boost::system::error_code& ec) - { - return this->get_service().non_blocking( - this->get_implementation(), mode, ec); - } - - /// Gets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native acceptor. This mode has no effect on the behaviour of the acceptor - * object's synchronous operations. - * - * @returns @c true if the underlying acceptor is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the acceptor object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native acceptor. - */ - bool native_non_blocking() const - { - return this->get_service().native_non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - boost::system::error_code native_non_blocking( - bool mode, boost::system::error_code& ec) - { - return this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @returns An object that represents the local endpoint of the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = this->get_service().local_endpoint( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the acceptor. - * Returns a default-constructed endpoint object if an error occurred and the - * error handler did not throw an exception. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return this->get_service().local_endpoint(this->get_implementation(), ec); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::socket socket(io_service); - * acceptor.accept(socket); - * @endcode - */ - template - void accept(basic_socket& peer, - typename enable_if::value>::type* = 0) - { - boost::system::error_code ec; - this->get_service().accept(this->get_implementation(), - peer, static_cast(0), ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::soocket socket(io_service); - * boost::system::error_code ec; - * acceptor.accept(socket, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - boost::system::error_code accept( - basic_socket& peer, - boost::system::error_code& ec, - typename enable_if::value>::type* = 0) - { - return this->get_service().accept(this->get_implementation(), - peer, static_cast(0), ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket. The function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::socket socket(io_service); - * acceptor.async_accept(socket, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket& peer, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if::value>::type* = 0) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - - return this->get_service().async_accept(this->get_implementation(), - peer, static_cast(0), - BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::socket socket(io_service); - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.accept(socket, endpoint); - * @endcode - */ - template - void accept(basic_socket& peer, - endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - this->get_service().accept(this->get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_service); - * ... - * boost::asio::ip::tcp::socket socket(io_service); - * boost::asio::ip::tcp::endpoint endpoint; - * boost::system::error_code ec; - * acceptor.accept(socket, endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - boost::system::error_code accept( - basic_socket& peer, - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - return this->get_service().accept( - this->get_implementation(), peer, &peer_endpoint, ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket, and additionally obtain the endpoint of the remote peer. The - * function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket& peer, - endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - - return this->get_service().async_accept(this->get_implementation(), peer, - &peer_endpoint, BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); - } -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP diff --git a/implementation/helper/1.55/boost/asio/basic_stream_socket_ext.hpp b/implementation/helper/1.55/boost/asio/basic_stream_socket_ext.hpp deleted file mode 100644 index ab55eda..0000000 --- a/implementation/helper/1.55/boost/asio/basic_stream_socket_ext.hpp +++ /dev/null @@ -1,855 +0,0 @@ -// -// basic_stream_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -/// Provides stream-oriented socket functionality. -/** - * The basic_stream_socket_ext class template provides asynchronous and blocking - * stream-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Concepts: - * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. - */ -template > -class basic_stream_socket_ext - : public basic_socket -{ -public: - /// (Deprecated: Use native_handle_type.) The native representation of a - /// socket. - typedef typename StreamSocketService::native_handle_type native_type; - - /// The native representation of a socket. - typedef typename StreamSocketService::native_handle_type native_handle_type; - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_stream_socket_ext without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param io_service The io_service object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_stream_socket_ext(boost::asio::io_service& io_service) - : basic_socket(io_service) - { - } - - /// Construct and open a basic_stream_socket_ext. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param io_service The io_service object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(boost::asio::io_service& io_service, - const protocol_type& protocol) - : basic_socket(io_service, protocol) - { - } - - /// Construct a basic_stream_socket_ext, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param io_service The io_service object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(boost::asio::io_service& io_service, - const endpoint_type& endpoint) - : basic_socket(io_service, endpoint) - { - } - - /// Construct a basic_stream_socket_ext on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param io_service The io_service object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(boost::asio::io_service& io_service, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket( - io_service, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_stream_socket_ext from another. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_service&) constructor. - */ - basic_stream_socket_ext(basic_stream_socket_ext&& other) - : basic_socket( - BOOST_ASIO_MOVE_CAST(basic_stream_socket_ext)(other)) - { - } - - /// Move-assign a basic_stream_socket_ext from another. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_service&) constructor. - */ - basic_stream_socket_ext& operator=(basic_stream_socket_ext&& other) - { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST(basic_stream_socket_ext)(other)); - return *this; - } - - /// Move-construct a basic_stream_socket_ext from a socket of another protocol - /// type. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_service&) constructor. - */ - template - basic_stream_socket_ext( - basic_stream_socket_ext&& other, - typename enable_if::value>::type* = 0) - : basic_socket( - BOOST_ASIO_MOVE_CAST2(basic_stream_socket_ext< - Protocol1, StreamSocketService1>)(other)) - { - } - - /// Move-assign a basic_stream_socket_ext from a socket of another protocol type. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_service&) constructor. - */ - template - typename enable_if::value, - basic_stream_socket_ext>::type& operator=( - basic_stream_socket_ext&& other) - { - basic_socket::operator=( - BOOST_ASIO_MOVE_CAST2(basic_stream_socket_ext< - Protocol1, StreamSocketService1>)(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. Returns 0 if an error occurred. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().send( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send( - this->get_implementation(), buffers, 0, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send( - this->get_implementation(), buffers, flags, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. Returns 0 if an error occurred. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @returns The number of bytes written. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.write_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "write_some"); - return s; - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes written. Returns 0 if an error occurred. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->get_service().send(this->get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous write. - /** - * This function is used to asynchronously write data to the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be written to the socket. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the write operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes written. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The write operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_write_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_write_some(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - return this->get_service().async_send(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @returns The number of bytes read. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.read_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "read_some"); - return s; - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes read. Returns 0 if an error occurred. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous read. - /** - * This function is used to asynchronously read data from the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be read. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the read operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes read. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_service::post(). - * - * @note The read operation may not read all of the requested number of bytes. - * Consider using the @ref async_read function if you need to ensure that the - * requested amount of data is read before the asynchronous operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_read_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_read_some(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - } -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.55/boost/asio/datagram_socket_service_ext.hpp b/implementation/helper/1.55/boost/asio/datagram_socket_service_ext.hpp deleted file mode 100644 index 7648581..0000000 --- a/implementation/helper/1.55/boost/asio/datagram_socket_service_ext.hpp +++ /dev/null @@ -1,437 +0,0 @@ -// -// datagram_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_EXT_ASIO_DATAGRAM_SOCKET_SERVICE_EXT_HPP -#define BOOST_EXT_ASIO_DATAGRAM_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include "detail/win_iocp_socket_service_ext.hpp" -#else -# include "detail/reactive_socket_service_ext.hpp" -#endif - -#include - -namespace boost { -namespace asio { - -/// Default service implementation for a datagram socket. -template -class datagram_socket_service_ext -#if defined(GENERATING_DOCUMENTATION) - : public boost::asio::io_service::service -#else - : public boost::asio::detail::service_base > -#endif -{ -public: -#if defined(GENERATING_DOCUMENTATION) - /// The unique service identifier. - static boost::asio::io_service::id id; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -private: - // The type of the platform-specific implementation. -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef detail::null_socket_service service_impl_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef detail::win_iocp_socket_service_ext service_impl_type; -#else - typedef detail::reactive_socket_service_ext service_impl_type; -#endif - -public: - /// The type of a datagram socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined implementation_type; -#else - typedef typename service_impl_type::implementation_type implementation_type; -#endif - - /// (Deprecated: Use native_handle_type.) The native socket type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_type; -#else - typedef typename service_impl_type::native_handle_type native_type; -#endif - - /// The native socket type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename service_impl_type::native_handle_type native_handle_type; -#endif - - /// Construct a new datagram socket service for the specified io_service. - explicit datagram_socket_service_ext(boost::asio::io_service& io_service) - : boost::asio::detail::service_base< - datagram_socket_service_ext >(io_service), - service_impl_(io_service) - { - } - - /// Construct a new datagram socket implementation. - void construct(implementation_type& impl) - { - service_impl_.construct(impl); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a new datagram socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - service_impl_.move_construct(impl, other_impl); - } - - /// Move-assign from another datagram socket implementation. - void move_assign(implementation_type& impl, - datagram_socket_service_ext& other_service, - implementation_type& other_impl) - { - service_impl_.move_assign(impl, other_service.service_impl_, other_impl); - } - - /// Move-construct a new datagram socket implementation from another protocol - /// type. - template - void converting_move_construct(implementation_type& impl, - typename datagram_socket_service_ext< - Protocol1>::implementation_type& other_impl, - typename enable_if::value>::type* = 0) - { - service_impl_.template converting_move_construct( - impl, other_impl); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroy a datagram socket implementation. - void destroy(implementation_type& impl) - { - service_impl_.destroy(impl); - } - - // Open a new datagram socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_DGRAM)) - service_impl_.open(impl, protocol, ec); - else - ec = boost::asio::error::invalid_argument; - return ec; - } - - /// Assign an existing native socket to a datagram socket. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - return service_impl_.assign(impl, protocol, native_socket, ec); - } - - /// Determine whether the socket is open. - bool is_open(const implementation_type& impl) const - { - return service_impl_.is_open(impl); - } - - /// Close a datagram socket implementation. - boost::system::error_code close(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.close(impl, ec); - } - - /// (Deprecated: Use native_handle().) Get the native socket implementation. - native_type native(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Get the native socket implementation. - native_handle_type native_handle(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Cancel all asynchronous operations associated with the socket. - boost::system::error_code cancel(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.cancel(impl, ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - bool at_mark(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.at_mark(impl, ec); - } - - /// Determine the number of bytes available for reading. - std::size_t available(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.available(impl, ec); - } - - // Bind the datagram socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - return service_impl_.bind(impl, endpoint, ec); - } - - /// Connect the datagram socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - return service_impl_.connect(impl, peer_endpoint, ec); - } - - /// Start an asynchronous connect. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - detail::async_result_init< - ConnectHandler, void (boost::system::error_code)> init( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); - - service_impl_.async_connect(impl, peer_endpoint, init.handler); - - return init.result.get(); - } - - /// Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const SettableSocketOption& option, boost::system::error_code& ec) - { - return service_impl_.set_option(impl, option, ec); - } - - /// Get a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - GettableSocketOption& option, boost::system::error_code& ec) const - { - return service_impl_.get_option(impl, option, ec); - } - - /// Perform an IO control command on the socket. - template - boost::system::error_code io_control(implementation_type& impl, - IoControlCommand& command, boost::system::error_code& ec) - { - return service_impl_.io_control(impl, command, ec); - } - - /// Gets the non-blocking mode of the socket. - bool non_blocking(const implementation_type& impl) const - { - return service_impl_.non_blocking(impl); - } - - /// Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - return service_impl_.non_blocking(impl, mode, ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const implementation_type& impl) const - { - return service_impl_.native_non_blocking(impl); - } - - /// Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - return service_impl_.native_non_blocking(impl, mode, ec); - } - - /// Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.local_endpoint(impl, ec); - } - - /// Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.remote_endpoint(impl, ec); - } - - /// Disable sends or receives on the socket. - boost::system::error_code shutdown(implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - return service_impl_.shutdown(impl, what, ec); - } - - /// Send the given data to the peer. - template - std::size_t send(implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.send(impl, buffers, flags, ec); - } - - /// Start an asynchronous send. - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(implementation_type& impl, const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - detail::async_result_init< - WriteHandler, void (boost::system::error_code, std::size_t)> init( - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - - service_impl_.async_send(impl, buffers, flags, init.handler); - - return init.result.get(); - } - - /// Send a datagram to the specified endpoint. - template - std::size_t send_to(implementation_type& impl, - const ConstBufferSequence& buffers, const endpoint_type& destination, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.send_to(impl, buffers, destination, flags, ec); - } - - /// Start an asynchronous send. - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, const endpoint_type& destination, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - detail::async_result_init< - WriteHandler, void (boost::system::error_code, std::size_t)> init( - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - - service_impl_.async_send_to(impl, buffers, - destination, flags, init.handler); - - return init.result.get(); - } - - /// Receive some data from the peer. - template - std::size_t receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.receive(impl, buffers, flags, ec); - } - - /// Start an asynchronous receive. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t)) - async_receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - detail::async_result_init< - ReadHandler, void (boost::system::error_code, std::size_t)> init( - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - - service_impl_.async_receive(impl, buffers, flags, init.handler); - - return init.result.get(); - } - - /// Receive a datagram with the endpoint of the sender. - template - std::size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.receive_from(impl, buffers, sender_endpoint, flags, - ec); - } - - /// Start an asynchronous receive that will get the endpoint of the sender. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - detail::async_result_init< - ReadHandler, void (boost::system::error_code, std::size_t)> init( - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - - service_impl_.async_receive_from(impl, buffers, - sender_endpoint, flags, init.handler); - - return init.result.get(); - } - -private: - // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - service_impl_.shutdown_service(); - } - - // The platform-specific implementation. - service_impl_type service_impl_; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext.hpp deleted file mode 100644 index 34b0375..0000000 --- a/implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext.hpp +++ /dev/null @@ -1,520 +0,0 @@ -// -// detail/handler_type_requirements_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -// Newer gcc, clang need special treatment to suppress unused typedef warnings. -#if defined(__clang__) -# if defined(__apple_build_version__) -# if (__clang_major__ >= 7) -# if !defined(BOOST_ASIO_UNUSED_TYPEDEF) -# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) -# endif -# endif // (__clang_major__ >= 7) -# elif ((__clang_major__ == 3) && (__clang_minor__ >= 6)) \ - || (__clang_major__ > 3) -# if !defined(BOOST_ASIO_UNUSED_TYPEDEF) -# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) -# endif -# endif // ((__clang_major__ == 3) && (__clang_minor__ >= 6)) - // || (__clang_major__ > 3) -#elif defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) -# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) -#endif // defined(__GNUC__) -#if !defined(BOOST_ASIO_UNUSED_TYPEDEF) -# define BOOST_ASIO_UNUSED_TYPEDEF -#endif // !defined(BOOST_ASIO_UNUSED_TYPEDEF) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1, *a2, *a3)), - char(0)); - -template -char (&three_arg_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - boost::asio::ip::address)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::three_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ComposedConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext_local.hpp b/implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext_local.hpp deleted file mode 100644 index 717eb6e..0000000 --- a/implementation/helper/1.55/boost/asio/detail/handler_type_requirements_ext_local.hpp +++ /dev/null @@ -1,536 +0,0 @@ -// -// detail/handler_type_requirements_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -// Newer gcc, clang need special treatment to suppress unused typedef warnings. -#if defined(__clang__) -# if defined(__apple_build_version__) -# if (__clang_major__ >= 7) -# if !defined(BOOST_ASIO_UNUSED_TYPEDEF) -# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) -# endif -# endif // (__clang_major__ >= 7) -# elif ((__clang_major__ == 3) && (__clang_minor__ >= 6)) \ - || (__clang_major__ > 3) -# if !defined(BOOST_ASIO_UNUSED_TYPEDEF) -# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) -# endif -# endif // ((__clang_major__ == 3) && (__clang_minor__ >= 6)) - // || (__clang_major__ > 3) -#elif defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) -# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) -#endif // defined(__GNUC__) -#if !defined(BOOST_ASIO_UNUSED_TYPEDEF) -# define BOOST_ASIO_UNUSED_TYPEDEF -#endif // !defined(BOOST_ASIO_UNUSED_TYPEDEF) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1, *a2, *a3)), - char(0)); - -template -char (&three_arg_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -template -auto four_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)(*a1, *a2, *a3, *a4)), - char(0)); - -template -char (&four_arg_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - std::uint32_t, \ - std::uint32_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::four_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ComposedConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp deleted file mode 100644 index 3b4a4a8..0000000 --- a/implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp +++ /dev/null @@ -1,270 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext::reactive_socket_service_base_ext( - boost::asio::io_service& io_service) - : reactor_(use_service(io_service)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext::shutdown_service() -{ -} - -void reactive_socket_service_base_ext::construct( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext::base_move_construct( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::base_move_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::destroy( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - } -} - -boost::system::error_code reactive_socket_service_base_ext::close( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - } - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::cancel( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_open( - reactive_socket_service_base_ext::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext::start_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext::start_accept_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, true, is_continuation, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext::start_connect_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP diff --git a/implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp b/implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp deleted file mode 100644 index 26521cf..0000000 --- a/implementation/helper/1.55/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp +++ /dev/null @@ -1,270 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local( - boost::asio::io_service& io_service) - : reactor_(use_service(io_service)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext_local::shutdown_service() -{ -} - -void reactive_socket_service_base_ext_local::construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext_local::base_move_construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::base_move_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::destroy( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - } -} - -boost::system::error_code reactive_socket_service_base_ext_local::close( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - } - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::cancel( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_open( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext_local::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext_local::start_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext_local::start_accept_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, true, is_continuation, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext_local::start_connect_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP diff --git a/implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext.ipp deleted file mode 100644 index fb6f77b..0000000 --- a/implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext.ipp +++ /dev/null @@ -1,230 +0,0 @@ -// -// detail/impl/socket_ops_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; - LPFN_WSARECVMSG WSARecvMsg; - DWORD NumberOfBytes; - - error_wrapper(WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, - &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, - &WSARecvMsg, sizeof WSARecvMsg, - &NumberOfBytes, NULL, NULL), ec); - if (ec.value() == SOCKET_ERROR) { - WSARecvMsg = NULL; - return 0; - } - - WSABUF wsaBuf; - WSAMSG msg; - char controlBuffer[1024]; - msg.name = addr; - msg.namelen = *addrlen; - wsaBuf.buf = bufs->buf; - wsaBuf.len = bufs->len; - msg.lpBuffers = &wsaBuf; - msg.dwBufferCount = count; - msg.Control.len = sizeof controlBuffer; - msg.Control.buf = controlBuffer; - msg.dwFlags = flags; - - DWORD dwNumberOfBytesRecvd; - signed_size_type result = error_wrapper(WSARecvMsg(s, &msg, &dwNumberOfBytesRecvd, NULL, NULL), ec); - - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = WSA_CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } else { - dwNumberOfBytesRecvd = -1; - } - return dwNumberOfBytesRecvd; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - char cmbuf[0x100]; - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - msg.msg_control = cmbuf; - msg.msg_controllen = sizeof(cmbuf); - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, boost::asio::ip::address& da) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP diff --git a/implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext_local.ipp b/implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext_local.ipp deleted file mode 100644 index b601e11..0000000 --- a/implementation/helper/1.55/boost/asio/detail/impl/socket_ops_ext_local.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/impl/socket_ops_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recv(socket_type s, buf* bufs, size_t count, - int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = error_wrapper(::WSARecv(s, bufs, - recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec); - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec = boost::system::error_code(); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - if (result >= 0) { - ec = boost::system::error_code(); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int tmp_addrlen = (int)*addrlen; - int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, - &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec); - *addrlen = (std::size_t)tmp_addrlen; - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec = boost::system::error_code(); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec = boost::system::error_code(); - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec, uid, gid); - - // Check for end of stream. - if (is_stream && bytes == 0) - { - ec = boost::asio::error::eof; - return true; - } - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext.hpp deleted file mode 100644 index 531ad21..0000000 --- a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext.hpp +++ /dev/null @@ -1,126 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recv_op_base_ext(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recv_op_base_ext::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static bool do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - return socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_); - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext : - public reactive_socket_recv_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext); - - reactive_socket_recv_op_ext(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recv_op_base_ext(socket, state, - buffers, flags, &reactive_socket_recv_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp deleted file mode 100644 index 6c151ca..0000000 --- a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp +++ /dev/null @@ -1,126 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recv_op_base_ext_local(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recv_op_base_ext_local::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static bool do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - return socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext_local : - public reactive_socket_recv_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext_local); - - reactive_socket_recv_op_ext_local(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recv_op_base_ext_local(socket, state, - buffers, flags, &reactive_socket_recv_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext_local* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp deleted file mode 100644 index 93bdf01..0000000 --- a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp +++ /dev/null @@ -1,136 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvfrom_op_base_ext(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvfrom_op_base_ext::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static bool do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - bool result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->da_); - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext : - public reactive_socket_recvfrom_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext); - - reactive_socket_recvfrom_op_ext(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recvfrom_op_base_ext( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp deleted file mode 100644 index a38844d..0000000 --- a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp +++ /dev/null @@ -1,136 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvfrom_op_base_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static bool do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - bool result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext_local : - public reactive_socket_recvfrom_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext_local); - - reactive_socket_recvfrom_op_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recvfrom_op_base_ext_local( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp deleted file mode 100644 index b28572b..0000000 --- a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp +++ /dev/null @@ -1,128 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvmsg_op_base_ext(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvmsg_op_base_ext::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static bool do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - return socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_); - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext : - public reactive_socket_recvmsg_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext); - - reactive_socket_recvmsg_op_ext(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - : reactive_socket_recvmsg_op_base_ext(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp deleted file mode 100644 index 7b5bc53..0000000 --- a/implementation/helper/1.55/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp +++ /dev/null @@ -1,128 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvmsg_op_base_ext_local(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvmsg_op_base_ext_local::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static bool do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - return socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_); - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext_local : - public reactive_socket_recvmsg_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext_local); - - reactive_socket_recvmsg_op_ext_local(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - : reactive_socket_recvmsg_op_base_ext_local(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - } - - static void do_complete(io_service_impl* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext.hpp deleted file mode 100644 index 3c0107c..0000000 --- a/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext.hpp +++ /dev/null @@ -1,455 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext( - boost::asio::io_service& io_service); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void shutdown_service(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, - "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext_local.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext_local.hpp deleted file mode 100644 index e97fca2..0000000 --- a/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_base_ext_local.hpp +++ /dev/null @@ -1,454 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext_local -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext_local( - boost::asio::io_service& io_service); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void shutdown_service(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, - "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext.hpp deleted file mode 100644 index 133301c..0000000 --- a/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext.hpp +++ /dev/null @@ -1,462 +0,0 @@ -// -// detail/reactive_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext : - public reactive_socket_service_base_ext -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext(boost::asio::io_service& io_service) - : reactive_socket_service_base_ext(io_service) - { - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - typename reactive_socket_service_ext< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(impl.socket_, protocol, - buffers, sender_endpoint, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, - const null_buffers&, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - if (!peer.assign(impl.protocol_, new_socket.get(), ec)) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects - // must be valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext_local.hpp b/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext_local.hpp deleted file mode 100644 index 7b444b3..0000000 --- a/implementation/helper/1.55/boost/asio/detail/reactive_socket_service_ext_local.hpp +++ /dev/null @@ -1,462 +0,0 @@ -// -// detail/reactive_socket_service_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext_local : - public reactive_socket_service_base_ext_local -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext_local::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext_local(boost::asio::io_service& io_service) - : reactive_socket_service_base_ext_local(io_service) - { - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - typename reactive_socket_service_ext_local< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(impl.socket_, protocol, - buffers, sender_endpoint, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, - const null_buffers&, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", - &impl, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - if (!peer.assign(impl.protocol_, new_socket.get(), ec)) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects - // must be valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(impl.socket_, handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/1.55/boost/asio/detail/reactor_op_ext.hpp deleted file mode 100644 index 948e016..0000000 --- a/implementation/helper/1.55/boost/asio/detail/reactor_op_ext.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// -// detail/reactor_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext - : public reactor_op -{ -public: - // The destination address - boost::asio::ip::address da_; - - reactor_op_ext(perform_func_type perform_func, func_type complete_func) - : reactor_op(perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/reactor_op_ext_local.hpp b/implementation/helper/1.55/boost/asio/detail/reactor_op_ext_local.hpp deleted file mode 100644 index a10d876..0000000 --- a/implementation/helper/1.55/boost/asio/detail/reactor_op_ext_local.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// detail/reactor_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext_local - : public reactor_op -{ -public: - // The passed credentials - std::uint32_t uid_; - std::uint32_t gid_; - - reactor_op_ext_local(perform_func_type perform_func, func_type complete_func) - : reactor_op(perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/1.55/boost/asio/detail/socket_ops_ext.hpp deleted file mode 100644 index 65b8ad8..0000000 --- a/implementation/helper/1.55/boost/asio/detail/socket_ops_ext.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// detail/socket_ops_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - boost::asio::ip::address& da); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - boost::asio::ip::address& da); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - boost::asio::ip::address& da); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/1.55/boost/asio/detail/socket_ops_ext_local.hpp b/implementation/helper/1.55/boost/asio/detail/socket_ops_ext_local.hpp deleted file mode 100644 index 77fd563..0000000 --- a/implementation/helper/1.55/boost/asio/detail/socket_ops_ext_local.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// -// detail/socket_ops_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recv(socket_type s, buf* bufs, - size_t count, int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/1.55/boost/asio/ip/udp_ext.hpp b/implementation/helper/1.55/boost/asio/ip/udp_ext.hpp deleted file mode 100644 index c622ff9..0000000 --- a/implementation/helper/1.55/boost/asio/ip/udp_ext.hpp +++ /dev/null @@ -1,115 +0,0 @@ -// -// ip/udp_ext.hpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_IP_UDP_EXT_HPP -#define BOOST_ASIO_IP_UDP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace ip { - -/// Encapsulates the flags needed for UDP. -/** - * The boost::asio::ip::udp_ext class contains flags necessary for UDP sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol, InternetProtocol. - */ -class udp_ext -{ -public: - /// The type of a UDP endpoint. - typedef basic_endpoint endpoint; - - /// Construct to represent the IPv4 UDP protocol. - static udp_ext v4() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET)); - } - - /// Construct to represent the IPv6 UDP protocol. - static udp_ext v6() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET6)); - } - - /// Obtain an identifier for the type of the protocol. - int type() const - { - return BOOST_ASIO_OS_DEF(SOCK_DGRAM); - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return BOOST_ASIO_OS_DEF(IPPROTO_UDP); - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return family_; - } - - /// The UDP socket type. - typedef basic_datagram_socket_ext socket; - - /// The UDP resolver type. - typedef basic_resolver resolver; - - /// Compare two protocols for equality. - friend bool operator==(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ == p2.family_; - } - - /// Compare two protocols for inequality. - friend bool operator!=(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ != p2.family_; - } - -private: - // Construct with a specific family. - explicit udp_ext(int protocol_family) - : family_(protocol_family) - { - } - - int family_; -}; - -} // namespace ip -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_IP_UDP_EXT_HPP diff --git a/implementation/helper/1.55/boost/asio/local/stream_protocol_ext.hpp b/implementation/helper/1.55/boost/asio/local/stream_protocol_ext.hpp deleted file mode 100644 index 6ccd0ad..0000000 --- a/implementation/helper/1.55/boost/asio/local/stream_protocol_ext.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// local/stream_protocol_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP -#define BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ - || defined(GENERATING_DOCUMENTATION) - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace local { - -/// Encapsulates the flags needed for stream-oriented UNIX sockets. -/** - * The boost::asio::local::stream_protocol class contains flags necessary for - * stream-oriented UNIX domain sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol. - */ -class stream_protocol_ext -{ -public: - /// Obtain an identifier for the type of the protocol. - int type() const - { - return SOCK_STREAM; - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return 0; - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return AF_UNIX; - } - - /// The type of a UNIX domain endpoint. - typedef basic_endpoint endpoint; - - /// The UNIX domain socket type. - typedef basic_stream_socket_ext socket; - - /// The UNIX domain acceptor type. - typedef basic_socket_acceptor_ext acceptor; - -#if !defined(BOOST_ASIO_NO_IOSTREAM) - /// The UNIX domain iostream type. - typedef basic_socket_iostream iostream; -#endif // !defined(BOOST_ASIO_NO_IOSTREAM) -}; - -} // namespace local -} // namespace asio -} // namespace boost - -#include - -#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) - // || defined(GENERATING_DOCUMENTATION) - -#endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP diff --git a/implementation/helper/1.55/boost/asio/socket_acceptor_service_ext.hpp b/implementation/helper/1.55/boost/asio/socket_acceptor_service_ext.hpp deleted file mode 100644 index 19a3bde..0000000 --- a/implementation/helper/1.55/boost/asio/socket_acceptor_service_ext.hpp +++ /dev/null @@ -1,305 +0,0 @@ -// -// socket_acceptor_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_EXT_HPP -#define BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#include - -namespace boost { -namespace asio { - -/// Default service implementation for a socket acceptor. -template -class socket_acceptor_service_ext -#if defined(GENERATING_DOCUMENTATION) - : public boost::asio::io_service::service -#else - : public boost::asio::detail::service_base > -#endif -{ -public: -#if defined(GENERATING_DOCUMENTATION) - /// The unique service identifier. - static boost::asio::io_service::id id; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename protocol_type::endpoint endpoint_type; - -private: - // The type of the platform-specific implementation. -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef detail::null_socket_service service_impl_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef detail::win_iocp_socket_service service_impl_type; -#else - typedef detail::reactive_socket_service_ext service_impl_type; -#endif - -public: - /// The native type of the socket acceptor. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined implementation_type; -#else - typedef typename service_impl_type::implementation_type implementation_type; -#endif - - /// (Deprecated: Use native_handle_type.) The native acceptor type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_type; -#else - typedef typename service_impl_type::native_handle_type native_type; -#endif - - /// The native acceptor type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename service_impl_type::native_handle_type native_handle_type; -#endif - - /// Construct a new socket acceptor service for the specified io_service. - explicit socket_acceptor_service_ext(boost::asio::io_service& io_service) - : boost::asio::detail::service_base< - socket_acceptor_service_ext >(io_service), - service_impl_(io_service) - { - } - - /// Construct a new socket acceptor implementation. - void construct(implementation_type& impl) - { - service_impl_.construct(impl); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a new socket acceptor implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - service_impl_.move_construct(impl, other_impl); - } - - /// Move-assign from another socket acceptor implementation. - void move_assign(implementation_type& impl, - socket_acceptor_service_ext& other_service, - implementation_type& other_impl) - { - service_impl_.move_assign(impl, other_service.service_impl_, other_impl); - } - - /// Move-construct a new socket acceptor implementation from another protocol - /// type. - template - void converting_move_construct(implementation_type& impl, - typename socket_acceptor_service_ext< - Protocol1>::implementation_type& other_impl, - typename enable_if::value>::type* = 0) - { - service_impl_.template converting_move_construct( - impl, other_impl); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroy a socket acceptor implementation. - void destroy(implementation_type& impl) - { - service_impl_.destroy(impl); - } - - /// Open a new socket acceptor implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - return service_impl_.open(impl, protocol, ec); - } - - /// Assign an existing native acceptor to a socket acceptor. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_acceptor, - boost::system::error_code& ec) - { - return service_impl_.assign(impl, protocol, native_acceptor, ec); - } - - /// Determine whether the acceptor is open. - bool is_open(const implementation_type& impl) const - { - return service_impl_.is_open(impl); - } - - /// Cancel all asynchronous operations associated with the acceptor. - boost::system::error_code cancel(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.cancel(impl, ec); - } - - /// Bind the socket acceptor to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - return service_impl_.bind(impl, endpoint, ec); - } - - /// Place the socket acceptor into the state where it will listen for new - /// connections. - boost::system::error_code listen(implementation_type& impl, int backlog, - boost::system::error_code& ec) - { - return service_impl_.listen(impl, backlog, ec); - } - - /// Close a socket acceptor implementation. - boost::system::error_code close(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.close(impl, ec); - } - - /// (Deprecated: Use native_handle().) Get the native acceptor implementation. - native_type native(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Get the native acceptor implementation. - native_handle_type native_handle(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const SettableSocketOption& option, boost::system::error_code& ec) - { - return service_impl_.set_option(impl, option, ec); - } - - /// Get a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - GettableSocketOption& option, boost::system::error_code& ec) const - { - return service_impl_.get_option(impl, option, ec); - } - - /// Perform an IO control command on the socket. - template - boost::system::error_code io_control(implementation_type& impl, - IoControlCommand& command, boost::system::error_code& ec) - { - return service_impl_.io_control(impl, command, ec); - } - - /// Gets the non-blocking mode of the acceptor. - bool non_blocking(const implementation_type& impl) const - { - return service_impl_.non_blocking(impl); - } - - /// Sets the non-blocking mode of the acceptor. - boost::system::error_code non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - return service_impl_.non_blocking(impl, mode, ec); - } - - /// Gets the non-blocking mode of the native acceptor implementation. - bool native_non_blocking(const implementation_type& impl) const - { - return service_impl_.native_non_blocking(impl); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - boost::system::error_code native_non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - return service_impl_.native_non_blocking(impl, mode, ec); - } - - /// Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.local_endpoint(impl, ec); - } - - /// Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - basic_socket& peer, - endpoint_type* peer_endpoint, boost::system::error_code& ec, - typename enable_if::value>::type* = 0) - { - return service_impl_.accept(impl, peer, peer_endpoint, ec); - } - - /// Start an asynchronous accept. - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(implementation_type& impl, - basic_socket& peer, - endpoint_type* peer_endpoint, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if::value>::type* = 0) - { - detail::async_result_init< - AcceptHandler, void (boost::system::error_code)> init( - BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); - - service_impl_.async_accept(impl, peer, peer_endpoint, init.handler); - - return init.result.get(); - } - -private: - // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - service_impl_.shutdown_service(); - } - - // The platform-specific implementation. - service_impl_type service_impl_; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_EXT_HPP diff --git a/implementation/helper/1.55/boost/asio/stream_socket_service_ext.hpp b/implementation/helper/1.55/boost/asio/stream_socket_service_ext.hpp deleted file mode 100644 index aaa13b3..0000000 --- a/implementation/helper/1.55/boost/asio/stream_socket_service_ext.hpp +++ /dev/null @@ -1,379 +0,0 @@ -// -// stream_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#include - -namespace boost { -namespace asio { - -/// Default service implementation for a stream socket. -template -class stream_socket_service_ext -#if defined(GENERATING_DOCUMENTATION) - : public boost::asio::io_service::service -#else - : public boost::asio::detail::service_base > -#endif -{ -public: -#if defined(GENERATING_DOCUMENTATION) - /// The unique service identifier. - static boost::asio::io_service::id id; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -private: - // The type of the platform-specific implementation. -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef detail::winrt_ssocket_service service_impl_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef detail::win_iocp_socket_service service_impl_type; -#else - typedef detail::reactive_socket_service_ext_local service_impl_type; -#endif - -public: - /// The type of a stream socket implementation. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined implementation_type; -#else - typedef typename service_impl_type::implementation_type implementation_type; -#endif - - /// (Deprecated: Use native_handle_type.) The native socket type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_type; -#else - typedef typename service_impl_type::native_handle_type native_type; -#endif - - /// The native socket type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename service_impl_type::native_handle_type native_handle_type; -#endif - - /// Construct a new stream socket service for the specified io_service. - explicit stream_socket_service_ext(boost::asio::io_service& io_service) - : boost::asio::detail::service_base< - stream_socket_service_ext >(io_service), - service_impl_(io_service) - { - } - - /// Construct a new stream socket implementation. - void construct(implementation_type& impl) - { - service_impl_.construct(impl); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a new stream socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - service_impl_.move_construct(impl, other_impl); - } - - /// Move-assign from another stream socket implementation. - void move_assign(implementation_type& impl, - stream_socket_service_ext& other_service, - implementation_type& other_impl) - { - service_impl_.move_assign(impl, other_service.service_impl_, other_impl); - } - - /// Move-construct a new stream socket implementation from another protocol - /// type. - template - void converting_move_construct(implementation_type& impl, - typename stream_socket_service_ext< - Protocol1>::implementation_type& other_impl, - typename enable_if::value>::type* = 0) - { - service_impl_.template converting_move_construct( - impl, other_impl); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroy a stream socket implementation. - void destroy(implementation_type& impl) - { - service_impl_.destroy(impl); - } - - /// Open a stream socket. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_STREAM)) - service_impl_.open(impl, protocol, ec); - else - ec = boost::asio::error::invalid_argument; - return ec; - } - - /// Assign an existing native socket to a stream socket. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - return service_impl_.assign(impl, protocol, native_socket, ec); - } - - /// Determine whether the socket is open. - bool is_open(const implementation_type& impl) const - { - return service_impl_.is_open(impl); - } - - /// Close a stream socket implementation. - boost::system::error_code close(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.close(impl, ec); - } - - /// (Deprecated: Use native_handle().) Get the native socket implementation. - native_type native(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Get the native socket implementation. - native_handle_type native_handle(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Cancel all asynchronous operations associated with the socket. - boost::system::error_code cancel(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.cancel(impl, ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - bool at_mark(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.at_mark(impl, ec); - } - - /// Determine the number of bytes available for reading. - std::size_t available(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.available(impl, ec); - } - - /// Bind the stream socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - return service_impl_.bind(impl, endpoint, ec); - } - - /// Connect the stream socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - return service_impl_.connect(impl, peer_endpoint, ec); - } - - /// Start an asynchronous connect. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - detail::async_result_init< - ConnectHandler, void (boost::system::error_code)> init( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); - - service_impl_.async_connect(impl, peer_endpoint, init.handler); - - return init.result.get(); - } - - /// Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const SettableSocketOption& option, boost::system::error_code& ec) - { - return service_impl_.set_option(impl, option, ec); - } - - /// Get a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - GettableSocketOption& option, boost::system::error_code& ec) const - { - return service_impl_.get_option(impl, option, ec); - } - - /// Perform an IO control command on the socket. - template - boost::system::error_code io_control(implementation_type& impl, - IoControlCommand& command, boost::system::error_code& ec) - { - return service_impl_.io_control(impl, command, ec); - } - - /// Gets the non-blocking mode of the socket. - bool non_blocking(const implementation_type& impl) const - { - return service_impl_.non_blocking(impl); - } - - /// Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - return service_impl_.non_blocking(impl, mode, ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const implementation_type& impl) const - { - return service_impl_.native_non_blocking(impl); - } - - /// Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - return service_impl_.native_non_blocking(impl, mode, ec); - } - - /// Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.local_endpoint(impl, ec); - } - - /// Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.remote_endpoint(impl, ec); - } - - /// Disable sends or receives on the socket. - boost::system::error_code shutdown(implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - return service_impl_.shutdown(impl, what, ec); - } - - /// Send the given data to the peer. - template - std::size_t send(implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.send(impl, buffers, flags, ec); - } - - /// Start an asynchronous send. - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - detail::async_result_init< - WriteHandler, void (boost::system::error_code, std::size_t)> init( - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); - - service_impl_.async_send(impl, buffers, flags, init.handler); - - return init.result.get(); - } - - /// Receive some data from the peer. - template - std::size_t receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.receive(impl, buffers, flags, ec); - } - - /// Start an asynchronous receive. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - detail::async_result_init< - ReadHandler, void (boost::system::error_code, std::size_t)> init( - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); - - service_impl_.async_receive(impl, buffers, flags, init.handler); - - return init.result.get(); - } - -private: - // Destroy all user-defined handler objects owned by the service. - void shutdown_service() - { - service_impl_.shutdown_service(); - } - - // The platform-specific implementation. - service_impl_type service_impl_; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/1.66/boost/asio/basic_datagram_socket_ext.hpp deleted file mode 100644 index 2820f81..0000000 --- a/implementation/helper/1.66/boost/asio/basic_datagram_socket_ext.hpp +++ /dev/null @@ -1,1043 +0,0 @@ -// -// basic_datagram_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -#include -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#include - -namespace boost { -namespace asio { - -/// Provides datagram-oriented socket functionality. -/** - * The basic_datagram_socket class template provides asynchronous and blocking - * datagram-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template )> -class basic_datagram_socket_ext - : public basic_socket_ext -{ -public: - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket_ext< - Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param io_context The io_context object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - */ - explicit basic_datagram_socket_ext(boost::asio::io_context& io_context) - : basic_socket_ext(io_context) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param io_context The io_context object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(boost::asio::io_context& io_context, - const protocol_type& protocol) - : basic_socket_ext(io_context, protocol) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param io_context The io_context object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(boost::asio::io_context& io_context, - const endpoint_type& endpoint) - : basic_socket_ext(io_context, endpoint) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param io_context The io_context object that the datagram socket will use - * to dispatch handlers for any asynchronous operations performed on the - * socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(boost::asio::io_context& io_context, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext( - io_context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_datagram_socket from another. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_context&) constructor. - */ - basic_datagram_socket_ext(basic_datagram_socket_ext&& other) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from another. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_context&) constructor. - */ - basic_datagram_socket_ext& operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_context&) constructor. - */ - template - basic_datagram_socket_ext( - basic_datagram_socket_ext&& other, - typename enable_if::value>::type* = 0) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(io_context&) constructor. - */ - template - typename enable_if::value, - basic_datagram_socket_ext>::type& operator=( - basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_datagram_socket_ext() - { - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code socket.send(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().send( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send(this->get_implementation(), - buffers, 0, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send(this->get_implementation(), - buffers, flags, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.send_to(boost::asio::buffer(data, size), destination); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send_to( - this->get_implementation(), buffers, destination, 0, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send_to( - this->get_implementation(), buffers, destination, flags, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->get_service().send_to(this->get_implementation(), - buffers, destination, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_send_to( - * boost::asio::buffer(data, size), destination, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, 0, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send_to( - this->get_implementation(), buffers, destination, 0, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send_to( - this->get_implementation(), buffers, destination, flags, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send_to( - this->get_implementation(), buffers, destination, flags, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.receive(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive(this->get_implementation(), - buffers, 0, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive(this->get_implementation(), - buffers, flags, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * boost::asio::ip::udp::endpoint sender_endpoint; - * socket.receive_from( - * boost::asio::buffer(data, size), sender_endpoint); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->get_service().receive_from(this->get_implementation(), - buffers, sender_endpoint, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.async_receive_from( - * boost::asio::buffer(data, size), sender_endpoint, handler); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, 0, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, - BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive_from( - this->get_implementation(), buffers, sender_endpoint, flags, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP diff --git a/implementation/helper/1.66/boost/asio/basic_socket_acceptor_ext.hpp b/implementation/helper/1.66/boost/asio/basic_socket_acceptor_ext.hpp deleted file mode 100644 index 92d71e3..0000000 --- a/implementation/helper/1.66/boost/asio/basic_socket_acceptor_ext.hpp +++ /dev/null @@ -1,1989 +0,0 @@ -// -// basic_socket_acceptor_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# include -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -# define BOOST_ASIO_SVC_T detail::null_socket_service -# elif defined(BOOST_ASIO_HAS_IOCP) -# include -# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service -# else -# include -# define BOOST_ASIO_SVC_T detail::reactive_socket_service_ext_local -# endif -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#include - -namespace boost { -namespace asio { - -/// Provides the ability to accept new connections. -/** - * The basic_socket_acceptor_ext class template is used for accepting new socket - * connections. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Example - * Opening a socket acceptor with the SO_REUSEADDR option enabled: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); - * acceptor.open(endpoint.protocol()); - * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ -template )> -class basic_socket_acceptor_ext - : BOOST_ASIO_SVC_ACCESS basic_io_object, - public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef io_context::executor_type executor_type; - - /// The native representation of an acceptor. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename BOOST_ASIO_SVC_T::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param io_context The io_context object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - */ - explicit basic_socket_acceptor_ext(boost::asio::io_context& io_context) - : basic_io_object(io_context) - { - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param io_context The io_context object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(boost::asio::io_context& io_context, - const protocol_type& protocol) - : basic_io_object(io_context) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param io_context The io_context object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor_ext acceptor(io_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(listen_backlog); - * @endcode - */ - basic_socket_acceptor_ext(boost::asio::io_context& io_context, - const endpoint_type& endpoint, bool reuse_addr = true) - : basic_io_object(io_context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - this->get_service().set_option(this->get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - this->get_service().listen(this->get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct a basic_socket_acceptor_ext on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param io_context The io_context object that the acceptor will use to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(boost::asio::io_context& io_context, - const protocol_type& protocol, const native_handle_type& native_acceptor) - : basic_io_object(io_context) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket_acceptor_ext from another. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor_ext(io_context&) constructor. - */ - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other) - : basic_io_object(std::move(other)) - { - } - - /// Move-assign a basic_socket_acceptor_ext from another. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor_ext(io_context&) constructor. - */ - basic_socket_acceptor_ext& operator=(basic_socket_acceptor_ext&& other) - { - basic_io_object::operator=(std::move(other)); - return *this; - } - - // All socket acceptors have access to each other's implementations. - template - friend class basic_socket_acceptor_ext; - - /// Move-construct a basic_socket_acceptor_ext from an acceptor of another - /// protocol type. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_ext_local(io_context&) constructor. - */ - template - basic_socket_acceptor_ext( - basic_socket_acceptor_ext&& other, - typename enable_if::value>::type* = 0) - : basic_io_object( - other.get_service(), other.get_implementation()) - { - } - - /// Move-assign a basic_socket_acceptor_ext from an acceptor of another protocol - /// type. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_ext_local(io_context&) constructor. - */ - template - typename enable_if::value, - basic_socket_acceptor_ext>::type& operator=( - basic_socket_acceptor_ext&& other) - { - basic_socket_acceptor_ext tmp(std::move(other)); - basic_io_object::operator=(std::move(tmp)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the acceptor. - /** - * This function destroys the acceptor, cancelling any outstanding - * asynchronous operations associated with the acceptor as if by calling - * @c cancel. - */ - ~basic_socket_acceptor_ext() - { - } - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - // These functions are provided by basic_io_object<>. -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -#if !defined(BOOST_ASIO_NO_DEPRECATED) - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_context() - { - return basic_io_object::get_io_context(); - } - - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_service() - { - return basic_io_object::get_io_service(); - } -#endif // !defined(BOOST_ASIO_NO_DEPRECATED) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return basic_io_object::get_executor(); - } -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * acceptor.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * boost::system::error_code ec; - * acceptor.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - this->get_service().open(this->get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_acceptor) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_acceptor, boost::system::error_code& ec) - { - this->get_service().assign(this->get_implementation(), - protocol, native_acceptor, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the acceptor is open. - bool is_open() const - { - return this->get_service().is_open(this->get_implementation()); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * acceptor.bind(endpoint); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * boost::system::error_code ec; - * acceptor.bind(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - this->get_service().bind(this->get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @throws boost::system::system_error Thrown on failure. - */ - void listen(int backlog = socket_base::max_listen_connections) - { - boost::system::error_code ec; - this->get_service().listen(this->get_implementation(), backlog, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::system::error_code ec; - * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec) - { - this->get_service().listen(this->get_implementation(), backlog, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @throws boost::system::system_error Thrown on failure. - */ - void close() - { - boost::system::error_code ec; - this->get_service().close(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::system::error_code ec; - * acceptor.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - this->get_service().close(this->get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = this->get_service().release( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return this->get_service().release(this->get_implementation(), ec); - } - - /// Get the native acceptor representation. - /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return this->get_service().native_handle(this->get_implementation()); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - */ - void cancel() - { - boost::system::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - this->get_service().cancel(this->get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * acceptor.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * boost::system::error_code ec; - * acceptor.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - this->get_service().set_option(this->get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * acceptor.get_option(option); - * bool is_set = option.get(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) - { - boost::system::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * boost::system::error_code ec; - * acceptor.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) - { - this->get_service().get_option(this->get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * socket.io_control(command); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - this->get_service().io_control(this->get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - this->get_service().io_control(this->get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the acceptor. - /** - * @returns @c true if the acceptor's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return this->get_service().non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().non_blocking(this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - this->get_service().non_blocking(this->get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native acceptor. This mode has no effect on the behaviour of the acceptor - * object's synchronous operations. - * - * @returns @c true if the underlying acceptor is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the acceptor object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native acceptor. - */ - bool native_non_blocking() const - { - return this->get_service().native_non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @returns An object that represents the local endpoint of the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = this->get_service().local_endpoint( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the acceptor. - * Returns a default-constructed endpoint object if an error occurred and the - * error handler did not throw an exception. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return this->get_service().local_endpoint(this->get_implementation(), ec); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - this->get_service().wait(this->get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::system::error_code ec; - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - this->get_service().wait(this->get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the acceptor to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for an acceptor to - * enter a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * acceptor.async_wait( - * boost::asio::ip::tcp::acceptor::wait_read, - * wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_wait(this->get_implementation(), - w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_wait(this->get_implementation(), - w, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(io_context); - * acceptor.accept(socket); - * @endcode - */ -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - void accept(basic_socket_ext_local& peer, - typename enable_if::value>::type* = 0) -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - void accept(basic_socket_ext_local& peer, - typename enable_if::value>::type* = 0) -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - { - boost::system::error_code ec; - this->get_service().accept(this->get_implementation(), - peer, static_cast(0), ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(io_context); - * boost::system::error_code ec; - * acceptor.accept(socket, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_SYNC_OP_VOID accept( - basic_socket_ext_local& peer, - boost::system::error_code& ec, - typename enable_if::value>::type* = 0) -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_SYNC_OP_VOID accept( - basic_socket_ext_local& peer, boost::system::error_code& ec, - typename enable_if::value>::type* = 0) -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - { - this->get_service().accept(this->get_implementation(), - peer, static_cast(0), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket. The function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(io_context); - * acceptor.async_accept(socket, accept_handler); - * @endcode - */ -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if::value>::type* = 0) -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if::value>::type* = 0) -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_accept(this->get_implementation(), - peer, static_cast(0), - BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_accept(this->get_implementation(), - peer, static_cast(0), init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.accept(socket, endpoint); - * @endcode - */ -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - void accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint) -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - void accept(basic_socket_ext_local& peer, endpoint_type& peer_endpoint) -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - { - boost::system::error_code ec; - this->get_service().accept(this->get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint; - * boost::system::error_code ec; - * acceptor.accept(socket, endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_SYNC_OP_VOID accept( - basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, boost::system::error_code& ec) -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - BOOST_ASIO_SYNC_OP_VOID accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, boost::system::error_code& ec) -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - { - this->get_service().accept( - this->get_implementation(), peer, &peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket, and additionally obtain the endpoint of the remote peer. The - * function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - */ -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_accept(this->get_implementation(), peer, - &peer_endpoint, BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_accept(this->get_implementation(), - peer, &peer_endpoint, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - typename Protocol::socket accept() - { - boost::system::error_code ec; - typename Protocol::socket peer( - this->get_service().accept( - this->get_implementation(), 0, 0, ec)); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept(boost::system::error_code& ec) - { - return this->get_service().accept(this->get_implementation(), 0, 0, ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * acceptor.async_accept(accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler, - handler, typename Protocol::socket) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_accept( - this->get_implementation(), static_cast(0), - static_cast(0), - BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_accept( - this->get_implementation(), static_cast(0), - static_cast(0), init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param io_context The io_context object to be used for the newly accepted - * socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - typename Protocol::socket accept(boost::asio::io_context& io_context) - { - boost::system::error_code ec; - typename Protocol::socket peer( - this->get_service().accept(this->get_implementation(), - &io_context, static_cast(0), ec)); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param io_context The io_context object to be used for the newly accepted - * socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(io_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept( - boost::asio::io_context& io_context, boost::system::error_code& ec) - { - return this->get_service().accept(this->get_implementation(), - &io_context, static_cast(0), ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param io_context The io_context object to be used for the newly accepted - * socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * acceptor.async_accept(io_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(boost::asio::io_context& io_context, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler, - handler, typename Protocol::socket) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_accept(this->get_implementation(), - &io_context, static_cast(0), - BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_accept(this->get_implementation(), - &io_context, static_cast(0), init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint)); - * @endcode - */ - typename Protocol::socket accept(endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - typename Protocol::socket peer( - this->get_service().accept(this->get_implementation(), - static_cast(0), &peer_endpoint, ec)); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept( - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - return this->get_service().accept(this->get_implementation(), - static_cast(0), &peer_endpoint, ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler, - handler, typename Protocol::socket) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_accept(this->get_implementation(), - static_cast(0), &peer_endpoint, - BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_accept(this->get_implementation(), - static_cast(0), &peer_endpoint, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param io_context The io_context object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(io_context2, endpoint)); - * @endcode - */ - typename Protocol::socket accept( - boost::asio::io_context& io_context, endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - typename Protocol::socket peer( - this->get_service().accept(this->get_implementation(), - &io_context, &peer_endpoint, ec)); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param io_context The io_context object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(io_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept(boost::asio::io_context& io_context, - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - return this->get_service().accept(this->get_implementation(), - &io_context, &peer_endpoint, ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param io_context The io_context object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(io_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(boost::asio::io_context& io_context, - endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK(MoveAcceptHandler, - handler, typename Protocol::socket) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_accept( - this->get_implementation(), &io_context, &peer_endpoint, - BOOST_ASIO_MOVE_CAST(MoveAcceptHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_accept(this->get_implementation(), - &io_context, &peer_endpoint, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) -}; - -} // namespace asio -} // namespace boost - -#include - -#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# undef BOOST_ASIO_SVC_T -#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/basic_socket_ext.hpp b/implementation/helper/1.66/boost/asio/basic_socket_ext.hpp deleted file mode 100644 index cdf4029..0000000 --- a/implementation/helper/1.66/boost/asio/basic_socket_ext.hpp +++ /dev/null @@ -1,1760 +0,0 @@ -// -// basic_socket_ext.hpp -// ~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -# define BOOST_ASIO_SVC_T detail::winrt_ssocket_service -# elif defined(BOOST_ASIO_HAS_IOCP) -# include -# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service -# else -# include -# define BOOST_ASIO_SVC_T detail::reactive_socket_service_ext -# endif -#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#include - -namespace boost { -namespace asio { - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext - : BOOST_ASIO_SVC_ACCESS basic_io_object, - public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef io_context::executor_type executor_type; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename BOOST_ASIO_SVC_T::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext(boost::asio::io_context& io_context) - : basic_io_object(io_context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(boost::asio::io_context& io_context, - const protocol_type& protocol) - : basic_io_object(io_context) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(boost::asio::io_context& io_context, - const endpoint_type& endpoint) - : basic_io_object(io_context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(boost::asio::io_context& io_context, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_io_object(io_context) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - basic_socket_ext(basic_socket_ext&& other) - : basic_io_object(std::move(other)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - basic_socket_ext& operator=(basic_socket_ext&& other) - { - basic_io_object::operator=(std::move(other)); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - template - basic_socket_ext(basic_socket_ext&& other, - typename enable_if::value>::type* = 0) - : basic_io_object( - other.get_service(), other.get_implementation()) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - template - typename enable_if::value, - basic_socket_ext>::type& operator=( - basic_socket_ext&& other) - { - basic_socket_ext tmp(std::move(other)); - basic_io_object::operator=(std::move(tmp)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - // These functions are provided by basic_io_object<>. -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -#if !defined(BOOST_ASIO_NO_DEPRECATED) - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_context() - { - return basic_io_object::get_io_context(); - } - - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_service() - { - return basic_io_object::get_io_service(); - } -#endif // !defined(BOOST_ASIO_NO_DEPRECATED) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return basic_io_object::get_executor(); - } -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - this->get_service().open(this->get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - this->get_service().assign(this->get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return this->get_service().is_open(this->get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - this->get_service().close(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - this->get_service().close(this->get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = this->get_service().release( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return this->get_service().release(this->get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return this->get_service().native_handle(this->get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - this->get_service().cancel(this->get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = this->get_service().at_mark(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return this->get_service().at_mark(this->get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = this->get_service().available( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return this->get_service().available(this->get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - this->get_service().bind(this->get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - this->get_service().open(this->get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - this->get_service().connect(this->get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - this->get_service().open(this->get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - this->get_service().connect(this->get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (!is_open()) - { - boost::system::error_code ec; - const protocol_type protocol = peer_endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); - if (ec) - { - async_completion init(handler); - - boost::asio::post(this->get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE( - ConnectHandler, void (boost::system::error_code)))( - init.completion_handler), ec)); - - return init.result.get(); - } - } - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_connect(this->get_implementation(), - peer_endpoint, BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_connect( - this->get_implementation(), peer_endpoint, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - this->get_service().set_option(this->get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - this->get_service().get_option(this->get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - this->get_service().io_control(this->get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - this->get_service().io_control(this->get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return this->get_service().non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().non_blocking(this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - this->get_service().non_blocking(this->get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return this->get_service().native_non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = this->get_service().local_endpoint( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return this->get_service().local_endpoint(this->get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = this->get_service().remote_endpoint( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return this->get_service().remote_endpoint(this->get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - this->get_service().shutdown(this->get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - this->get_service().shutdown(this->get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - this->get_service().wait(this->get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - this->get_service().wait(this->get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_wait(this->get_implementation(), - w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_wait(this->get_implementation(), - w, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext() - { - } - -private: - // Disallow copying and assignment. - basic_socket_ext(const basic_socket_ext&) BOOST_ASIO_DELETED; - basic_socket_ext& operator=(const basic_socket_ext&) BOOST_ASIO_DELETED; -}; - -} // namespace asio -} // namespace boost - -#include - -#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# undef BOOST_ASIO_SVC_T -#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/basic_socket_ext_local.hpp b/implementation/helper/1.66/boost/asio/basic_socket_ext_local.hpp deleted file mode 100644 index e13154c..0000000 --- a/implementation/helper/1.66/boost/asio/basic_socket_ext_local.hpp +++ /dev/null @@ -1,1760 +0,0 @@ -// -// basic_socket_ext_local.hpp -// ~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -# define BOOST_ASIO_SVC_T detail::winrt_ssocket_service -# elif defined(BOOST_ASIO_HAS_IOCP) -# include -# define BOOST_ASIO_SVC_T detail::win_iocp_socket_service -# else -# include -# define BOOST_ASIO_SVC_T detail::reactive_socket_service_ext_local -# endif -#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#include - -namespace boost { -namespace asio { - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext_local - : BOOST_ASIO_SVC_ACCESS basic_io_object, - public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef io_context::executor_type executor_type; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename BOOST_ASIO_SVC_T::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext_local lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext_local(boost::asio::io_context& io_context) - : basic_io_object(io_context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(boost::asio::io_context& io_context, - const protocol_type& protocol) - : basic_io_object(io_context) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(boost::asio::io_context& io_context, - const endpoint_type& endpoint) - : basic_io_object(io_context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param io_context The io_context object that the socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(boost::asio::io_context& io_context, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_io_object(io_context) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - basic_socket_ext_local(basic_socket_ext_local&& other) - : basic_io_object(std::move(other)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - basic_socket_ext_local& operator=(basic_socket_ext_local&& other) - { - basic_io_object::operator=(std::move(other)); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - template - basic_socket_ext_local(basic_socket_ext_local&& other, - typename enable_if::value>::type* = 0) - : basic_io_object( - other.get_service(), other.get_implementation()) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(io_context&) constructor. - */ - template - typename enable_if::value, - basic_socket_ext_local>::type& operator=( - basic_socket_ext_local&& other) - { - basic_socket_ext_local tmp(std::move(other)); - basic_io_object::operator=(std::move(tmp)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - // These functions are provided by basic_io_object<>. -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -#if !defined(BOOST_ASIO_NO_DEPRECATED) - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_context() - { - return basic_io_object::get_io_context(); - } - - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_service() - { - return basic_io_object::get_io_service(); - } -#endif // !defined(BOOST_ASIO_NO_DEPRECATED) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return basic_io_object::get_executor(); - } -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - this->get_service().open(this->get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - this->get_service().open(this->get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - this->get_service().assign(this->get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - this->get_service().assign(this->get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return this->get_service().is_open(this->get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - this->get_service().close(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - this->get_service().close(this->get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = this->get_service().release( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return this->get_service().release(this->get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return this->get_service().native_handle(this->get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - this->get_service().cancel(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - this->get_service().cancel(this->get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = this->get_service().at_mark(this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return this->get_service().at_mark(this->get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = this->get_service().available( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return this->get_service().available(this->get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - this->get_service().bind(this->get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - this->get_service().bind(this->get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - this->get_service().open(this->get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - this->get_service().connect(this->get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - this->get_service().open(this->get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - this->get_service().connect(this->get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(io_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (!is_open()) - { - boost::system::error_code ec; - const protocol_type protocol = peer_endpoint.protocol(); - this->get_service().open(this->get_implementation(), protocol, ec); - if (ec) - { - async_completion init(handler); - - boost::asio::post(this->get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE( - ConnectHandler, void (boost::system::error_code)))( - init.completion_handler), ec)); - - return init.result.get(); - } - } - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_connect(this->get_implementation(), - peer_endpoint, BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_connect( - this->get_implementation(), peer_endpoint, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - this->get_service().set_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - this->get_service().set_option(this->get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - this->get_service().get_option(this->get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - this->get_service().get_option(this->get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - this->get_service().io_control(this->get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - this->get_service().io_control(this->get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return this->get_service().non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().non_blocking(this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - this->get_service().non_blocking(this->get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return this->get_service().native_non_blocking(this->get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - this->get_service().native_non_blocking( - this->get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = this->get_service().local_endpoint( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return this->get_service().local_endpoint(this->get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = this->get_service().remote_endpoint( - this->get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return this->get_service().remote_endpoint(this->get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - this->get_service().shutdown(this->get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - this->get_service().shutdown(this->get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - this->get_service().wait(this->get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - this->get_service().wait(this->get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(io_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_wait(this->get_implementation(), - w, BOOST_ASIO_MOVE_CAST(WaitHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_wait(this->get_implementation(), - w, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext_local() - { - } - -private: - // Disallow copying and assignment. - basic_socket_ext_local(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - basic_socket_ext_local& operator=(const basic_socket_ext_local&) BOOST_ASIO_DELETED; -}; - -} // namespace asio -} // namespace boost - -#include - -#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# undef BOOST_ASIO_SVC_T -#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/basic_stream_socket_ext.hpp b/implementation/helper/1.66/boost/asio/basic_stream_socket_ext.hpp deleted file mode 100644 index 99d29c3..0000000 --- a/implementation/helper/1.66/boost/asio/basic_stream_socket_ext.hpp +++ /dev/null @@ -1,924 +0,0 @@ -// -// basic_stream_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# include -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#include - -namespace boost { -namespace asio { - -/// Provides stream-oriented socket functionality. -/** - * The basic_stream_socket_ext class template provides asynchronous and blocking - * stream-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Concepts: - * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. - */ -template )> -class basic_stream_socket_ext - : public basic_socket_ext_local -{ -public: - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket_ext_local< - Protocol BOOST_ASIO_SVC_TARG>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_stream_socket_ext without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param io_context The io_context object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_stream_socket_ext(boost::asio::io_context& io_context) - : basic_socket_ext_local(io_context) - { - } - - /// Construct and open a basic_stream_socket_ext. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param io_context The io_context object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(boost::asio::io_context& io_context, - const protocol_type& protocol) - : basic_socket_ext_local(io_context, protocol) - { - } - - /// Construct a basic_stream_socket_ext, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param io_context The io_context object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(boost::asio::io_context& io_context, - const endpoint_type& endpoint) - : basic_socket_ext_local(io_context, endpoint) - { - } - - /// Construct a basic_stream_socket_ext on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param io_context The io_context object that the stream socket will use to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(boost::asio::io_context& io_context, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext_local( - io_context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_stream_socket_ext from another. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_context&) constructor. - */ - basic_stream_socket_ext(basic_stream_socket_ext&& other) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket_ext from another. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_context&) constructor. - */ - basic_stream_socket_ext& operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_stream_socket_ext from a socket of another protocol - /// type. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_context&) constructor. - */ - template - basic_stream_socket_ext( - basic_stream_socket_ext&& other, - typename enable_if::value>::type* = 0) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket_ext from a socket of another protocol type. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket_ext object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket_ext(io_context&) constructor. - */ - template - typename enable_if::value, - basic_stream_socket_ext>::type& operator=( - basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_stream_socket_ext() - { - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. Returns 0 if an error occurred. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().send( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send( - this->get_implementation(), buffers, 0, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send( - this->get_implementation(), buffers, 0, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send( - this->get_implementation(), buffers, flags, - BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send( - this->get_implementation(), buffers, flags, - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. Returns 0 if an error occurred. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->get_service().receive( - this->get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive(this->get_implementation(), - buffers, 0, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive(this->get_implementation(), - buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive(this->get_implementation(), - buffers, flags, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @returns The number of bytes written. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.write_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().send( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "write_some"); - return s; - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes written. Returns 0 if an error occurred. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->get_service().send(this->get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous write. - /** - * This function is used to asynchronously write data to the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be written to the socket. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the write operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes written. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The write operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_write_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_write_some(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_send(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_send(this->get_implementation(), - buffers, 0, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @returns The number of bytes read. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.read_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "read_some"); - return s; - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes read. Returns 0 if an error occurred. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->get_service().receive( - this->get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous read. - /** - * This function is used to asynchronously read data from the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be read. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the read operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes read. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). - * - * @note The read operation may not read all of the requested number of bytes. - * Consider using the @ref async_read function if you need to ensure that the - * requested amount of data is read before the asynchronous operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_read_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_read_some(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_receive(this->get_implementation(), - buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion init(handler); - - this->get_service().async_receive(this->get_implementation(), - buffers, 0, init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - } -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext.hpp deleted file mode 100644 index 89f1594..0000000 --- a/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext.hpp +++ /dev/null @@ -1,565 +0,0 @@ -// -// detail/handler_type_requirements_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3)), - char(0)); - -template -char (&three_arg_handler_test(Handler, ...))[2]; - -template -auto three_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3 *a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3))), - char(0)); - -template -char (&three_arg_move_handler_test(Handler, ...))[2]; - - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - boost::asio::ip::address)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::three_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext_local.hpp deleted file mode 100644 index e12b1ca..0000000 --- a/implementation/helper/1.66/boost/asio/detail/handler_type_requirements_ext_local.hpp +++ /dev/null @@ -1,592 +0,0 @@ -// -// detail/handler_type_requirements_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - - -template -auto four_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3, *a4)), - char(0)); - -template -char (&four_arg_handler_test(Handler, ...))[2]; - -template -auto four_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3), BOOST_ASIO_MOVE_CAST(Arg4)(*a4))), - char(0)); - -template -char (&four_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - std::uint32_t, \ - std::uint32_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::four_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp deleted file mode 100644 index 6219e1f..0000000 --- a/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext::reactive_socket_service_base_ext( - boost::asio::io_context& io_context) - : io_context_(io_context), reactor_(use_service(io_context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext::base_shutdown() -{ -} - -void reactive_socket_service_base_ext::construct( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext::base_move_construct( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::base_move_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::destroy( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext::close( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext::cancel( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_open( - reactive_socket_service_base_ext::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext::start_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext::start_accept_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext::start_connect_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP diff --git a/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp b/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp deleted file mode 100644 index 02a628b..0000000 --- a/implementation/helper/1.66/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local( - boost::asio::io_context& io_context) - : io_context_(io_context), reactor_(use_service(io_context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext_local::base_shutdown() -{ -} - -void reactive_socket_service_base_ext_local::construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext_local::base_move_construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::base_move_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::destroy( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext_local::close( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext_local::cancel( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_open( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext_local::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext_local::start_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext_local::start_accept_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext_local::start_connect_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP diff --git a/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext.ipp deleted file mode 100644 index 4849766..0000000 --- a/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext.ipp +++ /dev/null @@ -1,230 +0,0 @@ -// -// detail/impl/socket_ops_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; - LPFN_WSARECVMSG WSARecvMsg; - DWORD NumberOfBytes; - - error_wrapper(WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, - &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, - &WSARecvMsg, sizeof WSARecvMsg, - &NumberOfBytes, NULL, NULL), ec); - if (ec.value() == SOCKET_ERROR) { - WSARecvMsg = NULL; - return 0; - } - - WSABUF wsaBuf; - WSAMSG msg; - char controlBuffer[1024]; - msg.name = addr; - msg.namelen = *addrlen; - wsaBuf.buf = bufs->buf; - wsaBuf.len = bufs->len; - msg.lpBuffers = &wsaBuf; - msg.dwBufferCount = count; - msg.Control.len = sizeof controlBuffer; - msg.Control.buf = controlBuffer; - msg.dwFlags = flags; - - DWORD dwNumberOfBytesRecvd; - signed_size_type result = error_wrapper(WSARecvMsg(s, &msg, &dwNumberOfBytesRecvd, NULL, NULL), ec); - - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = WSA_CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } else { - dwNumberOfBytesRecvd = -1; - } - return dwNumberOfBytesRecvd; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - char cmbuf[0x100]; - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - msg.msg_control = cmbuf; - msg.msg_controllen = sizeof(cmbuf); - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, boost::asio::ip::address& da) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP diff --git a/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext_local.ipp b/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext_local.ipp deleted file mode 100644 index 2a066b8..0000000 --- a/implementation/helper/1.66/boost/asio/detail/impl/socket_ops_ext_local.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/impl/socket_ops_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recv(socket_type s, buf* bufs, size_t count, - int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = error_wrapper(::WSARecv(s, bufs, - recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec); - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec = boost::system::error_code(); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - if (result >= 0) { - ec = boost::system::error_code(); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int tmp_addrlen = (int)*addrlen; - int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, - &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec); - *addrlen = (std::size_t)tmp_addrlen; - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec = boost::system::error_code(); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec = boost::system::error_code(); - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec, uid, gid); - - // Check for end of stream. - if (is_stream && bytes == 0) - { - ec = boost::asio::error::eof; - return true; - } - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext.hpp deleted file mode 100644 index 4f78284..0000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recv_op_base_ext(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recv_op_base_ext::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext : - public reactive_socket_recv_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext); - - reactive_socket_recv_op_ext(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recv_op_base_ext(socket, state, - buffers, flags, &reactive_socket_recv_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - handler_work::start(handler_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp deleted file mode 100644 index 994a495..0000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recv_op_base_ext_local(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recv_op_base_ext_local::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_) ? done : not_done; - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext_local : - public reactive_socket_recv_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext_local); - - reactive_socket_recv_op_ext_local(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recv_op_base_ext_local(socket, state, - buffers, flags, &reactive_socket_recv_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - handler_work::start(handler_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext_local* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp deleted file mode 100644 index 969e8ab..0000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp +++ /dev/null @@ -1,141 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvfrom_op_base_ext(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvfrom_op_base_ext::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->da_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext : - public reactive_socket_recvfrom_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext); - - reactive_socket_recvfrom_op_ext(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recvfrom_op_base_ext( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - handler_work::start(handler_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp deleted file mode 100644 index a8a2af7..0000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp +++ /dev/null @@ -1,141 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvfrom_op_base_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext_local : - public reactive_socket_recvfrom_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext_local); - - reactive_socket_recvfrom_op_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler) - : reactive_socket_recvfrom_op_base_ext_local( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - handler_work::start(handler_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp deleted file mode 100644 index 0efd6c3..0000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp +++ /dev/null @@ -1,135 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvmsg_op_base_ext(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvmsg_op_base_ext::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext : - public reactive_socket_recvmsg_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext); - - reactive_socket_recvmsg_op_ext(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - : reactive_socket_recvmsg_op_base_ext(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - handler_work::start(handler_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp deleted file mode 100644 index c992283..0000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp +++ /dev/null @@ -1,135 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvmsg_op_base_ext_local(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvmsg_op_base_ext_local::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext_local : - public reactive_socket_recvmsg_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext_local); - - reactive_socket_recvmsg_op_ext_local(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - : reactive_socket_recvmsg_op_base_ext_local(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) - { - handler_work::start(handler_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext.hpp deleted file mode 100644 index b6a80bd..0000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext.hpp +++ /dev/null @@ -1,517 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext( - boost::asio::io_context& io_context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - boost_asio_handler_alloc_helpers::allocate( - sizeof(op), handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, - "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The io_context that owns this socket service - io_context& io_context_; - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext_local.hpp deleted file mode 100644 index e233574..0000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_base_ext_local.hpp +++ /dev/null @@ -1,514 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext_local -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext_local( - boost::asio::io_context& io_context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The io_context that owns this socket service. - io_context& io_context_; - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext.hpp deleted file mode 100644 index 761f2bb..0000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext.hpp +++ /dev/null @@ -1,531 +0,0 @@ -// -// detail/reactive_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext : - public service_base >, - public reactive_socket_service_base_ext -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext(boost::asio::io_context& io_context) - : service_base >(io_context), - reactive_socket_service_base_ext(io_context) - { - } - - // Destroy all user-defined handler objects owned by the service - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext&, - typename reactive_socket_service_ext< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(impl.socket_, protocol, - buffers, sender_endpoint, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, - const null_buffers&, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Accept a new connection. - typename Protocol::socket accept(implementation_type& impl, - io_context* peer_io_context, endpoint_type* peer_endpoint, - boost::system::error_code& ec) - { - typename Protocol::socket peer( - peer_io_context ? *peer_io_context : io_context_); - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return peer; - } - #endif // defined(BOOST_ASIO_HAS_MOVE) - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_accept(implementation_type& impl, - boost::asio::io_context* peer_io_context, - endpoint_type* peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(peer_io_context ? *peer_io_context : io_context_, - impl.socket_, impl.state_, impl.protocol_, peer_endpoint, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext_local.hpp deleted file mode 100644 index a946851..0000000 --- a/implementation/helper/1.66/boost/asio/detail/reactive_socket_service_ext_local.hpp +++ /dev/null @@ -1,529 +0,0 @@ -// -// detail/reactive_socket_service_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext_local : - public service_base >, - public reactive_socket_service_base_ext_local -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext_local::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext_local(boost::asio::io_context& io_context) - : service_base >(io_context), - reactive_socket_service_base_ext_local(io_context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext_local&, - typename reactive_socket_service_ext_local< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(impl.socket_, protocol, - buffers, sender_endpoint, flags, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, - const null_buffers&, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Accept a new connection. - typename Protocol::socket accept(implementation_type& impl, - io_context* peer_io_context, endpoint_type* peer_endpoint, - boost::system::error_code& ec) - { - typename Protocol::socket peer( - peer_io_context ? *peer_io_context : io_context_); - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return peer; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_accept(implementation_type& impl, - boost::asio::io_context* peer_io_context, - endpoint_type* peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(peer_io_context ? *peer_io_context : io_context_, - impl.socket_, impl.state_, impl.protocol_, peer_endpoint, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, Handler& handler) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, handler); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/1.66/boost/asio/detail/reactor_op_ext.hpp deleted file mode 100644 index 04c2c70..0000000 --- a/implementation/helper/1.66/boost/asio/detail/reactor_op_ext.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// -// detail/reactor_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext - : public reactor_op -{ -public: - // The destination address - boost::asio::ip::address da_; - - reactor_op_ext(perform_func_type perform_func, func_type complete_func) - : reactor_op(perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/reactor_op_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/reactor_op_ext_local.hpp deleted file mode 100644 index 3a27272..0000000 --- a/implementation/helper/1.66/boost/asio/detail/reactor_op_ext_local.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// -// detail/reactor_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext_local - : public reactor_op -{ -public: - - // The passed credentials - std::uint32_t uid_; - std::uint32_t gid_; - - reactor_op_ext_local(perform_func_type perform_func, func_type complete_func) - : reactor_op(perform_func, complete_func) - { - } -}; - - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/1.66/boost/asio/detail/socket_ops_ext.hpp deleted file mode 100644 index cc28d9c..0000000 --- a/implementation/helper/1.66/boost/asio/detail/socket_ops_ext.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// detail/socket_ops_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - boost::asio::ip::address& da); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - boost::asio::ip::address& da); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - boost::asio::ip::address& da); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/1.66/boost/asio/detail/socket_ops_ext_local.hpp b/implementation/helper/1.66/boost/asio/detail/socket_ops_ext_local.hpp deleted file mode 100644 index e08a643..0000000 --- a/implementation/helper/1.66/boost/asio/detail/socket_ops_ext_local.hpp +++ /dev/null @@ -1,95 +0,0 @@ -// -// detail/socket_ops_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recv(socket_type s, buf* bufs, - size_t count, int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recv(socket_type s, state_type state, buf* bufs, - size_t count, int flags, bool all_empty, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recv(state_type state, - const weak_cancel_token_type& cancel_token, bool all_empty, - boost::system::error_code& ec, size_t bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.66/boost/asio/ip/udp_ext.hpp b/implementation/helper/1.66/boost/asio/ip/udp_ext.hpp deleted file mode 100644 index 6ce2ac4..0000000 --- a/implementation/helper/1.66/boost/asio/ip/udp_ext.hpp +++ /dev/null @@ -1,115 +0,0 @@ -// -// ip/udp_ext.hpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_IP_UDP_EXT_HPP -#define BOOST_ASIO_IP_UDP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace ip { - -/// Encapsulates the flags needed for UDP. -/** - * The boost::asio::ip::udp_ext class contains flags necessary for UDP sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol, InternetProtocol. - */ -class udp_ext -{ -public: - /// The type of a UDP endpoint. - typedef basic_endpoint endpoint; - - /// Construct to represent the IPv4 UDP protocol. - static udp_ext v4() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET)); - } - - /// Construct to represent the IPv6 UDP protocol. - static udp_ext v6() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET6)); - } - - /// Obtain an identifier for the type of the protocol. - int type() const - { - return BOOST_ASIO_OS_DEF(SOCK_DGRAM); - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return BOOST_ASIO_OS_DEF(IPPROTO_UDP); - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return family_; - } - - /// The UDP socket type. - typedef basic_datagram_socket_ext socket; - - /// The UDP resolver type. - typedef basic_resolver resolver; - - /// Compare two protocols for equality. - friend bool operator==(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ == p2.family_; - } - - /// Compare two protocols for inequality. - friend bool operator!=(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ != p2.family_; - } - -private: - // Construct with a specific family. - explicit udp_ext(int protocol_family) - : family_(protocol_family) - { - } - - int family_; -}; - -} // namespace ip -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_IP_UDP_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/local/stream_protocol_ext.hpp b/implementation/helper/1.66/boost/asio/local/stream_protocol_ext.hpp deleted file mode 100644 index 6ccd0ad..0000000 --- a/implementation/helper/1.66/boost/asio/local/stream_protocol_ext.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// local/stream_protocol_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP -#define BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ - || defined(GENERATING_DOCUMENTATION) - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace local { - -/// Encapsulates the flags needed for stream-oriented UNIX sockets. -/** - * The boost::asio::local::stream_protocol class contains flags necessary for - * stream-oriented UNIX domain sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol. - */ -class stream_protocol_ext -{ -public: - /// Obtain an identifier for the type of the protocol. - int type() const - { - return SOCK_STREAM; - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return 0; - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return AF_UNIX; - } - - /// The type of a UNIX domain endpoint. - typedef basic_endpoint endpoint; - - /// The UNIX domain socket type. - typedef basic_stream_socket_ext socket; - - /// The UNIX domain acceptor type. - typedef basic_socket_acceptor_ext acceptor; - -#if !defined(BOOST_ASIO_NO_IOSTREAM) - /// The UNIX domain iostream type. - typedef basic_socket_iostream iostream; -#endif // !defined(BOOST_ASIO_NO_IOSTREAM) -}; - -} // namespace local -} // namespace asio -} // namespace boost - -#include - -#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) - // || defined(GENERATING_DOCUMENTATION) - -#endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP diff --git a/implementation/helper/1.66/boost/asio/stream_socket_service_ext.hpp b/implementation/helper/1.66/boost/asio/stream_socket_service_ext.hpp deleted file mode 100644 index ff5c5f8..0000000 --- a/implementation/helper/1.66/boost/asio/stream_socket_service_ext.hpp +++ /dev/null @@ -1,415 +0,0 @@ -// -// stream_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#include - -namespace boost { -namespace asio { - -/// Default service implementation for a stream socket. -template -class stream_socket_service_ext -#if defined(GENERATING_DOCUMENTATION) - : public boost::asio::io_context::service -#else - : public boost::asio::detail::service_base > -#endif -{ -public: -#if defined(GENERATING_DOCUMENTATION) - /// The unique service identifier. - static boost::asio::io_context::id id; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -private: - // The type of the platform-specific implementation. -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef detail::winrt_ssocket_service service_impl_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef detail::win_iocp_socket_service service_impl_type; -#else - typedef detail::reactive_socket_service_ext_local service_impl_type; -#endif - -public: - /// The type of a stream socket implementation. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined implementation_type; -#else - typedef typename service_impl_type::implementation_type implementation_type; -#endif - - /// The native socket type. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename service_impl_type::native_handle_type native_handle_type; -#endif - - /// Construct a new stream socket service for the specified io_context. - explicit stream_socket_service_ext(boost::asio::io_context& io_context) - : boost::asio::detail::service_base< - stream_socket_service_ext >(io_context), - service_impl_(io_context) - { - } - - /// Construct a new stream socket implementation. - void construct(implementation_type& impl) - { - service_impl_.construct(impl); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a new stream socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - service_impl_.move_construct(impl, other_impl); - } - - /// Move-assign from another stream socket implementation. - void move_assign(implementation_type& impl, - stream_socket_service_ext& other_service, - implementation_type& other_impl) - { - service_impl_.move_assign(impl, other_service.service_impl_, other_impl); - } - - // All socket services have access to each other's implementations. - template friend class stream_socket_service_ext; - - /// Move-construct a new stream socket implementation from another protocol - /// type. - template - void converting_move_construct(implementation_type& impl, - stream_socket_service_ext& other_service, - typename stream_socket_service_ext< - Protocol1>::implementation_type& other_impl, - typename enable_if::value>::type* = 0) - { - service_impl_.template converting_move_construct( - impl, other_service.service_impl_, other_impl); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroy a stream socket implementation. - void destroy(implementation_type& impl) - { - service_impl_.destroy(impl); - } - - /// Open a stream socket. - BOOST_ASIO_SYNC_OP_VOID open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_STREAM)) - service_impl_.open(impl, protocol, ec); - else - ec = boost::asio::error::invalid_argument; - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to a stream socket. - BOOST_ASIO_SYNC_OP_VOID assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - service_impl_.assign(impl, protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open(const implementation_type& impl) const - { - return service_impl_.is_open(impl); - } - - /// Close a stream socket implementation. - BOOST_ASIO_SYNC_OP_VOID close(implementation_type& impl, - boost::system::error_code& ec) - { - service_impl_.close(impl, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying socket. - native_handle_type release(implementation_type& impl, - boost::system::error_code& ec) - { - return service_impl_.release(impl, ec); - } - - /// Get the native socket implementation. - native_handle_type native_handle(implementation_type& impl) - { - return service_impl_.native_handle(impl); - } - - /// Cancel all asynchronous operations associated with the socket. - BOOST_ASIO_SYNC_OP_VOID cancel(implementation_type& impl, - boost::system::error_code& ec) - { - service_impl_.cancel(impl, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - bool at_mark(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.at_mark(impl, ec); - } - - /// Determine the number of bytes available for reading. - std::size_t available(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.available(impl, ec); - } - - /// Bind the stream socket to the specified local endpoint. - BOOST_ASIO_SYNC_OP_VOID bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - service_impl_.bind(impl, endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the stream socket to the specified endpoint. - BOOST_ASIO_SYNC_OP_VOID connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - service_impl_.connect(impl, peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - async_completion init(handler); - - service_impl_.async_connect(impl, peer_endpoint, init.completion_handler); - - return init.result.get(); - } - - /// Set a socket option. - template - BOOST_ASIO_SYNC_OP_VOID set_option(implementation_type& impl, - const SettableSocketOption& option, boost::system::error_code& ec) - { - service_impl_.set_option(impl, option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get a socket option. - template - BOOST_ASIO_SYNC_OP_VOID get_option(const implementation_type& impl, - GettableSocketOption& option, boost::system::error_code& ec) const - { - service_impl_.get_option(impl, option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - template - BOOST_ASIO_SYNC_OP_VOID io_control(implementation_type& impl, - IoControlCommand& command, boost::system::error_code& ec) - { - service_impl_.io_control(impl, command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - bool non_blocking(const implementation_type& impl) const - { - return service_impl_.non_blocking(impl); - } - - /// Sets the non-blocking mode of the socket. - BOOST_ASIO_SYNC_OP_VOID non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - service_impl_.non_blocking(impl, mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const implementation_type& impl) const - { - return service_impl_.native_non_blocking(impl); - } - - /// Sets the non-blocking mode of the native socket implementation. - BOOST_ASIO_SYNC_OP_VOID native_non_blocking(implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - service_impl_.native_non_blocking(impl, mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.local_endpoint(impl, ec); - } - - /// Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - return service_impl_.remote_endpoint(impl, ec); - } - - /// Disable sends or receives on the socket. - BOOST_ASIO_SYNC_OP_VOID shutdown(implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - service_impl_.shutdown(impl, what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - BOOST_ASIO_SYNC_OP_VOID wait(implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - service_impl_.wait(impl, w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(implementation_type& impl, socket_base::wait_type w, - BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - async_completion init(handler); - - service_impl_.async_wait(impl, w, init.completion_handler); - - return init.result.get(); - } - - /// Send the given data to the peer. - template - std::size_t send(implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.send(impl, buffers, flags, ec); - } - - /// Start an asynchronous send. - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - async_completion init(handler); - - service_impl_.async_send(impl, buffers, flags, init.completion_handler); - - return init.result.get(); - } - - /// Receive some data from the peer. - template - std::size_t receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return service_impl_.receive(impl, buffers, flags, ec); - } - - /// Start an asynchronous receive. - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - async_completion init(handler); - - service_impl_.async_receive(impl, buffers, flags, init.completion_handler); - - return init.result.get(); - } - -private: - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - service_impl_.shutdown(); - } - - // The platform-specific implementation. - service_impl_type service_impl_; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - -#endif // BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/1.70/boost/asio/basic_datagram_socket_ext.hpp deleted file mode 100644 index 58a553f..0000000 --- a/implementation/helper/1.70/boost/asio/basic_datagram_socket_ext.hpp +++ /dev/null @@ -1,1118 +0,0 @@ -// -// basic_datagram_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_datagram_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL) - -/// Provides datagram-oriented socket functionality. -/** - * The basic_datagram_socket class template provides asynchronous and blocking - * datagram-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_datagram_socket_ext - : public basic_socket_ext -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_datagram_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket_ext::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_datagram_socket_ext(const executor_type& ex) - : basic_socket_ext(ex) - { - } - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_datagram_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, const protocol_type& protocol) - : basic_socket_ext(ex, protocol) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, protocol) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket_ext(ex, endpoint) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, endpoint) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext(ex, protocol, native_socket) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_datagram_socket from another. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - basic_datagram_socket_ext(basic_datagram_socket_ext&& other) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from another. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - basic_datagram_socket_ext& operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - template - basic_datagram_socket_ext(basic_datagram_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_datagram_socket_ext& - >::type operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_datagram_socket_ext() - { - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code socket.send(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, buffers, flags); - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.send_to(boost::asio::buffer(data, size), destination); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send_to( - this->impl_.get_implementation(), buffers, destination, 0, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send_to( - this->impl_.get_implementation(), buffers, destination, flags, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->impl_.get_service().send_to(this->impl_.get_implementation(), - buffers, destination, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_send_to( - * boost::asio::buffer(data, size), destination, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send_to(), handler, this, buffers, - destination, socket_base::message_flags(0)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send_to(), handler, this, buffers, destination, flags); - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.receive(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, buffers, flags); - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * boost::asio::ip::udp::endpoint sender_endpoint; - * socket.receive_from( - * boost::asio::buffer(data, size), sender_endpoint); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.async_receive_from( - * boost::asio::buffer(data, size), sender_endpoint, handler); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive_from(), handler, this, buffers, - &sender_endpoint, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive_from(), handler, - this, buffers, &sender_endpoint, flags); - } - -private: - struct initiate_async_send - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_datagram_socket_ext* self, const ConstBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_send_to - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_datagram_socket_ext* self, const ConstBufferSequence& buffers, - const endpoint_type& destination, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send_to( - self->impl_.get_implementation(), buffers, destination, flags, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_receive - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_datagram_socket_ext* self, const MutableBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_receive_from - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_datagram_socket_ext* self, const MutableBufferSequence& buffers, - endpoint_type* sender_endpoint, socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive_from( - self->impl_.get_implementation(), buffers, *sender_endpoint, flags, - handler2.value, self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/basic_socket_acceptor_ext.hpp b/implementation/helper/1.70/boost/asio/basic_socket_acceptor_ext.hpp deleted file mode 100644 index e3e2966..0000000 --- a/implementation/helper/1.70/boost/asio/basic_socket_acceptor_ext.hpp +++ /dev/null @@ -1,2381 +0,0 @@ -// -// basic_socket_acceptor_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_acceptor_ext; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL) - -/// Provides the ability to accept new connections. -/** - * The basic_socket_acceptor_ext class template is used for accepting new socket - * connections. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Example - * Opening a socket acceptor with the SO_REUSEADDR option enabled: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); - * acceptor.open(endpoint.protocol()); - * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ -template -class basic_socket_acceptor_ext - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// The native representation of an acceptor. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext_local< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - */ - explicit basic_socket_acceptor_ext(const executor_type& ex) - : impl_(ex) - { - } - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - */ - template - explicit basic_socket_acceptor_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(const executor_type& ex, const protocol_type& protocol) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor acceptor(my_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ - basic_socket_acceptor_ext(const executor_type& ex, - const endpoint_type& endpoint, bool reuse_addr = true) - : impl_(ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - impl_.get_service().set_option(impl_.get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - impl_.get_service().listen(impl_.get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor acceptor(my_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const endpoint_type& endpoint, bool reuse_addr = true, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - impl_.get_service().set_option(impl_.get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - impl_.get_service().listen(impl_.get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct a basic_socket_acceptor on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_acceptor) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket_acceptor on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_acceptor, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket_acceptor from another. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket_acceptor from another. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - basic_socket_acceptor_ext& operator=(basic_socket_acceptor_ext&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All socket acceptors have access to each other's implementations. - template - friend class basic_socket_acceptor_ext; - - /// Move-construct a basic_socket_acceptor from an acceptor of another - /// protocol type. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - template - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket_acceptor from an acceptor of another protocol - /// type. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_acceptor_ext& - >::type operator=(basic_socket_acceptor_ext&& other) - { - basic_socket_acceptor_ext tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the acceptor. - /** - * This function destroys the acceptor, cancelling any outstanding - * asynchronous operations associated with the acceptor as if by calling - * @c cancel. - */ - ~basic_socket_acceptor_ext() - { - } - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * acceptor.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::system::error_code ec; - * acceptor.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_acceptor) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_acceptor, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the acceptor is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * acceptor.bind(endpoint); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * boost::system::error_code ec; - * acceptor.bind(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @throws boost::system::system_error Thrown on failure. - */ - void listen(int backlog = socket_base::max_listen_connections) - { - boost::system::error_code ec; - impl_.get_service().listen(impl_.get_implementation(), backlog, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec) - { - impl_.get_service().listen(impl_.get_implementation(), backlog, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @throws boost::system::system_error Thrown on failure. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native acceptor representation. - /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - */ - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * acceptor.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * boost::system::error_code ec; - * acceptor.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * acceptor.get_option(option); - * bool is_set = option.get(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * boost::system::error_code ec; - * acceptor.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * socket.io_control(command); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the acceptor. - /** - * @returns @c true if the acceptor's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native acceptor. This mode has no effect on the behaviour of the acceptor - * object's synchronous operations. - * - * @returns @c true if the underlying acceptor is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the acceptor object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native acceptor. - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @returns An object that represents the local endpoint of the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the acceptor. - * Returns a default-constructed endpoint object if an error occurred and the - * error handler did not throw an exception. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the acceptor to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for an acceptor to - * enter a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_wait( - * boost::asio::ip::tcp::acceptor::wait_read, - * wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * acceptor.accept(socket); - * @endcode - */ - template - void accept(basic_socket_ext_local& peer, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - impl_.get_service().accept(impl_.get_implementation(), - peer, static_cast(0), ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * acceptor.accept(socket, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID accept( - basic_socket_ext_local& peer, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - impl_.get_service().accept(impl_.get_implementation(), - peer, static_cast(0), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket. The function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * acceptor.async_accept(socket, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - return async_initiate( - initiate_async_accept(), handler, this, - &peer, static_cast(0)); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.accept(socket, endpoint); - * @endcode - */ - template - void accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint; - * boost::system::error_code ec; - * acceptor.accept(socket, endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - impl_.get_service().accept( - impl_.get_implementation(), peer, &peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket, and additionally obtain the endpoint of the remote peer. The - * function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) - { - return async_initiate( - initiate_async_accept(), handler, this, &peer, &peer_endpoint); - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - typename Protocol::socket accept() - { - boost::system::error_code ec; - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept(boost::system::error_code& ec) - { - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - return async_initiate( - initiate_async_move_accept(), handler, this, - impl_.get_executor(), static_cast(0), - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly - * accepted socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, - typename enable_if< - is_executor::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, boost::system::error_code& ec, - typename enable_if< - is_executor::value - >::type* = 0) - { - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * Executor1>::other peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(my_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - Executor1>::other)) - async_accept(const Executor1& ex, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_executor::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - Executor1>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - ex, static_cast(0), - static_cast(0)); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * typename ExecutionContext::executor_type>::other peer - * // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(my_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other)) - async_accept(ExecutionContext& context, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - context.get_executor(), static_cast(0), - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint)); - * @endcode - */ - typename Protocol::socket accept(endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept( - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - return async_initiate( - initiate_async_move_accept(), handler, this, - impl_.get_executor(), &peer_endpoint, - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint)); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, endpoint_type& peer_endpoint, - typename enable_if< - is_executor::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint)); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, endpoint_type& peer_endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const executor_type& ex, - endpoint_type& peer_endpoint, boost::system::error_code& ec, - typename enable_if< - is_executor::value - >::type* = 0) - { - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, - endpoint_type& peer_endpoint, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * Executor1>::other peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(my_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - Executor1>::other)) - async_accept(const Executor1& ex, endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_executor::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - Executor1>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - ex, &peer_endpoint, - static_cast(0)); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * typename ExecutionContext::executor_type>::other peer - * // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(my_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other)) - async_accept(ExecutionContext& context, - endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - context.get_executor(), &peer_endpoint, - static_cast(0)); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - -private: - // Disallow copying and assignment. - basic_socket_acceptor_ext(const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED; - basic_socket_acceptor_ext& operator=( - const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_acceptor_ext* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_accept - { - template - void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - basic_socket_acceptor_ext* self, basic_socket_ext_local* peer, - endpoint_type* peer_endpoint) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_accept( - self->impl_.get_implementation(), *peer, peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_move_accept - { - template - void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - basic_socket_acceptor_ext* self, const Executor1& peer_ex, - endpoint_type* peer_endpoint, Socket*) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( - MoveAcceptHandler, handler, Socket) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_move_accept( - self->impl_.get_implementation(), peer_ex, peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext_local, Executor> impl_; -#endif -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/basic_socket_ext.hpp b/implementation/helper/1.70/boost/asio/basic_socket_ext.hpp deleted file mode 100644 index 523f97a..0000000 --- a/implementation/helper/1.70/boost/asio/basic_socket_ext.hpp +++ /dev/null @@ -1,1859 +0,0 @@ -// -// basic_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL) - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext(const executor_type& ex) - : impl_(ex) - { - } - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const protocol_type& protocol) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : impl_(ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const protocol_type& protocol, - const native_handle_type& native_socket) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const protocol_type& protocol, - const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext(basic_socket_ext&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext& operator=(basic_socket_ext&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket_ext; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - basic_socket_ext(basic_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_ext& - >::type operator=(basic_socket_ext && other) - { - basic_socket_ext tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return impl_.get_service().at_mark(impl_.get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = impl_.get_service().available( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return impl_.get_service().available(impl_.get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - boost::system::error_code open_ec; - if (!is_open()) - { - const protocol_type protocol = peer_endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); - } - - return async_initiate( - initiate_async_connect(), handler, this, peer_endpoint, open_ec); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().remote_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext() - { - } - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext, Executor> impl_; -#endif - -private: - // Disallow copying and assignment. - basic_socket_ext(const basic_socket_ext&) BOOST_ASIO_DELETED; - basic_socket_ext& operator=(const basic_socket_ext&) BOOST_ASIO_DELETED; - - struct initiate_async_connect - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, - basic_socket_ext* self, const endpoint_type& peer_endpoint, - const boost::system::error_code& open_ec) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (open_ec) - { - boost::asio::post(self->impl_.get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); - } - else - { - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_connect( - self->impl_.get_implementation(), peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - } - }; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_ext* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/basic_socket_ext_local.hpp b/implementation/helper/1.70/boost/asio/basic_socket_ext_local.hpp deleted file mode 100644 index 855d01c..0000000 --- a/implementation/helper/1.70/boost/asio/basic_socket_ext_local.hpp +++ /dev/null @@ -1,1859 +0,0 @@ -// -// basic_socket_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_ext_local; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL) - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext_local - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_socket_ext_local other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext_local< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext_local lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext_local(const executor_type& ex) - : impl_(ex) - { - } - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_socket_ext_local(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const endpoint_type& endpoint) - : impl_(ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol, - const native_handle_type& native_socket) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol, - const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext_local(basic_socket_ext_local&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext_local& operator=(basic_socket_ext_local&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket_ext_local; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - basic_socket_ext_local(basic_socket_ext_local&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_ext_local& - >::type operator=(basic_socket_ext_local && other) - { - basic_socket_ext_local tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return impl_.get_service().at_mark(impl_.get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = impl_.get_service().available( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return impl_.get_service().available(impl_.get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - boost::system::error_code open_ec; - if (!is_open()) - { - const protocol_type protocol = peer_endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); - } - - return async_initiate( - initiate_async_connect(), handler, this, peer_endpoint, open_ec); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().remote_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext_local() - { - } - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext_local, Executor> impl_; -#endif - -private: - // Disallow copying and assignment. - basic_socket_ext_local(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - basic_socket_ext_local& operator=(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - - struct initiate_async_connect - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, - basic_socket_ext_local* self, const endpoint_type& peer_endpoint, - const boost::system::error_code& open_ec) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (open_ec) - { - boost::asio::post(self->impl_.get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); - } - else - { - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_connect( - self->impl_.get_implementation(), peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - } - }; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_ext_local* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/basic_stream_socket_ext.hpp b/implementation/helper/1.70/boost/asio/basic_stream_socket_ext.hpp deleted file mode 100644 index 325157a..0000000 --- a/implementation/helper/1.70/boost/asio/basic_stream_socket_ext.hpp +++ /dev/null @@ -1,996 +0,0 @@ -// -// basic_stream_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_stream_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL) - -/// Provides stream-oriented socket functionality. -/** - * The basic_stream_socket_ext class template provides asynchronous and blocking - * stream-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Concepts: - * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. - */ -template -class basic_stream_socket_ext - : public basic_socket_ext_local -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_stream_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_stream_socket without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_stream_socket_ext(const executor_type& ex) - : basic_socket_ext_local(ex) - { - } - - /// Construct a basic_stream_socket without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_stream_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context) - { - } - - /// Construct and open a basic_stream_socket. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, const protocol_type& protocol) - : basic_socket_ext_local(ex, protocol) - { - } - - /// Construct and open a basic_stream_socket. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, protocol) - { - } - - /// Construct a basic_stream_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket_ext_local(ex, endpoint) - { - } - - /// Construct a basic_stream_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, endpoint) - { - } - - /// Construct a basic_stream_socket on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext_local(ex, protocol, native_socket) - { - } - - /// Construct a basic_stream_socket on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_stream_socket from another. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - basic_stream_socket_ext(basic_stream_socket_ext&& other) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket from another. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - basic_stream_socket_ext& operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_stream_socket from a socket of another protocol - /// type. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - template - basic_stream_socket_ext(basic_stream_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket from a socket of another protocol type. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_stream_socket_ext& - >::type operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_stream_socket_ext() - { - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. Returns 0 if an error occurred. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, buffers, flags); - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. Returns 0 if an error occurred. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, buffers, flags); - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @returns The number of bytes written. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.write_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "write_some"); - return s; - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes written. Returns 0 if an error occurred. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous write. - /** - * This function is used to asynchronously write data to the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be written to the socket. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the write operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes written. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The write operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_write_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_write_some(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @returns The number of bytes read. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.read_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "read_some"); - return s; - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes read. Returns 0 if an error occurred. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous read. - /** - * This function is used to asynchronously read data from the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be read. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the read operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes read. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The read operation may not read all of the requested number of bytes. - * Consider using the @ref async_read function if you need to ensure that the - * requested amount of data is read before the asynchronous operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_read_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_read_some(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - -private: - struct initiate_async_send - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_stream_socket_ext* self, const ConstBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_receive - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_stream_socket_ext* self, const MutableBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext.hpp deleted file mode 100644 index 67fe6bd..0000000 --- a/implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext.hpp +++ /dev/null @@ -1,586 +0,0 @@ -// -// detail/handler_type_requirements_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3)), - char(0)); - -template -char (&three_arg_handler_test(Handler, ...))[2]; - -template -auto three_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3 *a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3))), - char(0)); - -template -char (&three_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - boost::asio::ip::address)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::three_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext_local.hpp deleted file mode 100644 index 65640ad..0000000 --- a/implementation/helper/1.70/boost/asio/detail/handler_type_requirements_ext_local.hpp +++ /dev/null @@ -1,588 +0,0 @@ -// -// detail/handler_type_requirements_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto four_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3, *a4)), - char(0)); - -template -char (&four_arg_handler_test(Handler, ...))[2]; - -template -auto four_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3), BOOST_ASIO_MOVE_CAST(Arg4)(*a4))), - char(0)); - -template -char (&four_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - std::uint32_t, std::uint32_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::four_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp deleted file mode 100644 index 04036ad..0000000 --- a/implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext::reactive_socket_service_base_ext( - execution_context& context) - : reactor_(use_service(context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext::base_shutdown() -{ -} - -void reactive_socket_service_base_ext::construct( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext::base_move_construct( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::base_move_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::destroy( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext::close( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext::cancel( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_open( - reactive_socket_service_base_ext::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext::start_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext::start_accept_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext::start_connect_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP diff --git a/implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp b/implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp deleted file mode 100644 index 288cf19..0000000 --- a/implementation/helper/1.70/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local( - execution_context& context) - : reactor_(use_service(context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext_local::base_shutdown() -{ -} - -void reactive_socket_service_base_ext_local::construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext_local::base_move_construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::base_move_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::destroy( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext_local::close( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext_local::cancel( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_open( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext_local::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext_local::start_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext_local::start_accept_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext_local::start_connect_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP diff --git a/implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext.ipp deleted file mode 100644 index a4546ca..0000000 --- a/implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext.ipp +++ /dev/null @@ -1,230 +0,0 @@ -// -// detail/impl/socket_ops_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; - LPFN_WSARECVMSG WSARecvMsg; - DWORD NumberOfBytes; - - error_wrapper(WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, - &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, - &WSARecvMsg, sizeof WSARecvMsg, - &NumberOfBytes, NULL, NULL), ec); - if (ec.value() == SOCKET_ERROR) { - WSARecvMsg = NULL; - return 0; - } - - WSABUF wsaBuf; - WSAMSG msg; - char controlBuffer[1024]; - msg.name = addr; - msg.namelen = *addrlen; - wsaBuf.buf = bufs->buf; - wsaBuf.len = bufs->len; - msg.lpBuffers = &wsaBuf; - msg.dwBufferCount = count; - msg.Control.len = sizeof controlBuffer; - msg.Control.buf = controlBuffer; - msg.dwFlags = flags; - - DWORD dwNumberOfBytesRecvd; - signed_size_type result = error_wrapper(WSARecvMsg(s, &msg, &dwNumberOfBytesRecvd, NULL, NULL), ec); - - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = WSA_CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } else { - dwNumberOfBytesRecvd = -1; - } - return dwNumberOfBytesRecvd; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - char cmbuf[0x100]; - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - msg.msg_control = cmbuf; - msg.msg_controllen = sizeof(cmbuf); - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, boost::asio::ip::address& da) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP diff --git a/implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext_local.ipp b/implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext_local.ipp deleted file mode 100644 index 5050f24..0000000 --- a/implementation/helper/1.70/boost/asio/detail/impl/socket_ops_ext_local.ipp +++ /dev/null @@ -1,303 +0,0 @@ -// -// detail/impl/socket_ops_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recv(socket_type s, buf* bufs, size_t count, - int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = error_wrapper(::WSARecv(s, bufs, - recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec); - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec = boost::system::error_code(); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - if (result >= 0) { - ec = boost::system::error_code(); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int tmp_addrlen = (int)*addrlen; - int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, - &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec); - *addrlen = (std::size_t)tmp_addrlen; - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec = boost::system::error_code(); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec = boost::system::error_code(); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec, uid, gid); - - // Check for end of stream. - if (is_stream && bytes == 0) - { - ec = boost::asio::error::eof; - return true; - } - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext.hpp deleted file mode 100644 index da8cd83..0000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext.hpp +++ /dev/null @@ -1,140 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recv_op_base_ext(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recv_op_base_ext::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext : - public reactive_socket_recv_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext); - - reactive_socket_recv_op_ext(socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - : reactive_socket_recv_op_base_ext(socket, state, - buffers, flags, &reactive_socket_recv_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - io_executor_(io_ex) - { - handler_work::start(handler_, io_executor_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_, o->io_executor_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - IoExecutor io_executor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp deleted file mode 100644 index ce5ca28..0000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp +++ /dev/null @@ -1,140 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recv_op_base_ext_local(socket_type socket, - socket_ops::state_type state, const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recv_op_base_ext_local::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_) ? done : not_done; - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext_local : - public reactive_socket_recv_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext_local); - - reactive_socket_recv_op_ext_local(socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - : reactive_socket_recv_op_base_ext_local(socket, state, - buffers, flags, &reactive_socket_recv_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - io_executor_(io_ex) - { - handler_work::start(handler_, io_executor_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext_local* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_, o->io_executor_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3, handler.arg4)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - IoExecutor io_executor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp deleted file mode 100644 index 6cc2443..0000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvfrom_op_base_ext(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvfrom_op_base_ext::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->da_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext : - public reactive_socket_recvfrom_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext); - - reactive_socket_recvfrom_op_ext(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvfrom_op_base_ext( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - io_executor_(io_ex) - { - handler_work::start(handler_, io_executor_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_, o->io_executor_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - IoExecutor io_executor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp deleted file mode 100644 index 81485ff..0000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvfrom_op_base_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext_local : - public reactive_socket_recvfrom_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext_local); - - reactive_socket_recvfrom_op_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvfrom_op_base_ext_local( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - io_executor_(io_ex) - { - handler_work::start(handler_, io_executor_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_, o->io_executor_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - IoExecutor io_executor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp deleted file mode 100644 index cd02730..0000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvmsg_op_base_ext(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvmsg_op_base_ext::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext : - public reactive_socket_recvmsg_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext); - - reactive_socket_recvmsg_op_ext(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvmsg_op_base_ext(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - io_executor_(io_ex) - { - handler_work::start(handler_, io_executor_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_, o->io_executor_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - IoExecutor io_executor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp deleted file mode 100644 index 059cddb..0000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvmsg_op_base_ext_local(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvmsg_op_base_ext_local::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext_local : - public reactive_socket_recvmsg_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext_local); - - reactive_socket_recvmsg_op_ext_local(socket_type socket, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvmsg_op_base_ext_local(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - io_executor_(io_ex) - { - handler_work::start(handler_, io_executor_); - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - handler_work w(o->handler_, o->io_executor_); - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - IoExecutor io_executor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext.hpp deleted file mode 100644 index 3fc3a5a..0000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext.hpp +++ /dev/null @@ -1,521 +0,0 @@ -// -// detail/reactive_socket_service_base.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext(execution_context& context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op< - ConstBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, - in_flags, out_flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext_local.hpp deleted file mode 100644 index 8c5503f..0000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_base_ext_local.hpp +++ /dev/null @@ -1,521 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext_local -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext_local(execution_context& context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op< - ConstBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext_local< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext_local< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, - in_flags, out_flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext.hpp deleted file mode 100644 index 1eae357..0000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext.hpp +++ /dev/null @@ -1,508 +0,0 @@ -// -// detail/reactive_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext : - public execution_context_service_base >, - public reactive_socket_service_base_ext -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext(execution_context& context) - : execution_context_service_base< - reactive_socket_service_ext >(context), - reactive_socket_service_base_ext(context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext&, - typename reactive_socket_service_ext< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, - destination, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(impl.socket_, protocol, buffers, - sender_endpoint, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_move_accept(implementation_type& impl, - const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(peer_io_ex, impl.socket_, impl.state_, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext_local.hpp deleted file mode 100644 index e55cfb1..0000000 --- a/implementation/helper/1.70/boost/asio/detail/reactive_socket_service_ext_local.hpp +++ /dev/null @@ -1,508 +0,0 @@ -// -// detail/reactive_socket_service_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext_local : - public execution_context_service_base >, - public reactive_socket_service_base_ext_local -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext_local::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext_local(execution_context& context) - : execution_context_service_base< - reactive_socket_service_ext_local >(context), - reactive_socket_service_base_ext_local(context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext_local&, - typename reactive_socket_service_ext_local< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, buffers, - destination, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(impl.socket_, protocol, buffers, - sender_endpoint, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_move_accept(implementation_type& impl, - const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(peer_io_ex, impl.socket_, impl.state_, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(impl.socket_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/1.70/boost/asio/detail/reactor_op_ext.hpp deleted file mode 100644 index b267cf6..0000000 --- a/implementation/helper/1.70/boost/asio/detail/reactor_op_ext.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// -// detail/reactor_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext - : public reactor_op -{ -public: - // The destination address - boost::asio::ip::address da_; - - reactor_op_ext(perform_func_type perform_func, func_type complete_func) - : reactor_op(perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/reactor_op_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/reactor_op_ext_local.hpp deleted file mode 100644 index cd81ffb..0000000 --- a/implementation/helper/1.70/boost/asio/detail/reactor_op_ext_local.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// detail/reactor_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext_local - : public reactor_op -{ -public: - // Credentials - std::uint32_t uid_; - std::uint32_t gid_; - - reactor_op_ext_local(perform_func_type perform_func, func_type complete_func) - : reactor_op(perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/1.70/boost/asio/detail/socket_ops_ext.hpp deleted file mode 100644 index 9285fed..0000000 --- a/implementation/helper/1.70/boost/asio/detail/socket_ops_ext.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// detail/socket_ops_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - boost::asio::ip::address& da); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - boost::asio::ip::address& da); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - boost::asio::ip::address& da); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/1.70/boost/asio/detail/socket_ops_ext_local.hpp b/implementation/helper/1.70/boost/asio/detail/socket_ops_ext_local.hpp deleted file mode 100644 index f494d79..0000000 --- a/implementation/helper/1.70/boost/asio/detail/socket_ops_ext_local.hpp +++ /dev/null @@ -1,95 +0,0 @@ -// -// detail/socket_ops_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recv(socket_type s, buf* bufs, - size_t count, int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recv(socket_type s, state_type state, buf* bufs, - size_t count, int flags, bool all_empty, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recv(state_type state, - const weak_cancel_token_type& cancel_token, bool all_empty, - boost::system::error_code& ec, size_t bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.70/boost/asio/ip/udp_ext.hpp b/implementation/helper/1.70/boost/asio/ip/udp_ext.hpp deleted file mode 100644 index 6ce2ac4..0000000 --- a/implementation/helper/1.70/boost/asio/ip/udp_ext.hpp +++ /dev/null @@ -1,115 +0,0 @@ -// -// ip/udp_ext.hpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_IP_UDP_EXT_HPP -#define BOOST_ASIO_IP_UDP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace ip { - -/// Encapsulates the flags needed for UDP. -/** - * The boost::asio::ip::udp_ext class contains flags necessary for UDP sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol, InternetProtocol. - */ -class udp_ext -{ -public: - /// The type of a UDP endpoint. - typedef basic_endpoint endpoint; - - /// Construct to represent the IPv4 UDP protocol. - static udp_ext v4() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET)); - } - - /// Construct to represent the IPv6 UDP protocol. - static udp_ext v6() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET6)); - } - - /// Obtain an identifier for the type of the protocol. - int type() const - { - return BOOST_ASIO_OS_DEF(SOCK_DGRAM); - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return BOOST_ASIO_OS_DEF(IPPROTO_UDP); - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return family_; - } - - /// The UDP socket type. - typedef basic_datagram_socket_ext socket; - - /// The UDP resolver type. - typedef basic_resolver resolver; - - /// Compare two protocols for equality. - friend bool operator==(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ == p2.family_; - } - - /// Compare two protocols for inequality. - friend bool operator!=(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ != p2.family_; - } - -private: - // Construct with a specific family. - explicit udp_ext(int protocol_family) - : family_(protocol_family) - { - } - - int family_; -}; - -} // namespace ip -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_IP_UDP_EXT_HPP diff --git a/implementation/helper/1.70/boost/asio/local/stream_protocol_ext.hpp b/implementation/helper/1.70/boost/asio/local/stream_protocol_ext.hpp deleted file mode 100644 index 7c57c62..0000000 --- a/implementation/helper/1.70/boost/asio/local/stream_protocol_ext.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// local/stream_protocol_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP -#define BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ - || defined(GENERATING_DOCUMENTATION) - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace local { - -/// Encapsulates the flags needed for stream-oriented UNIX sockets. -/** - * The boost::asio::local::stream_protocol class contains flags necessary for - * stream-oriented UNIX domain sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol. - */ -class stream_protocol_ext -{ -public: - /// Obtain an identifier for the type of the protocol. - int type() const - { - return SOCK_STREAM; - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return 0; - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return AF_UNIX; - } - - /// The type of a UNIX domain endpoint. - typedef basic_endpoint endpoint; - - /// The UNIX domain socket type. - typedef basic_stream_socket_ext socket; - - /// The UNIX domain acceptor type. - typedef basic_socket_acceptor_ext acceptor; - -#if !defined(BOOST_ASIO_NO_IOSTREAM) - /// The UNIX domain iostream type. - typedef basic_socket_iostream iostream; -#endif // !defined(BOOST_ASIO_NO_IOSTREAM) -}; - -} // namespace local -} // namespace asio -} // namespace boost - -#include - -#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) - // || defined(GENERATING_DOCUMENTATION) - -#endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/1.74/boost/asio/basic_datagram_socket_ext.hpp deleted file mode 100644 index 49a4950..0000000 --- a/implementation/helper/1.74/boost/asio/basic_datagram_socket_ext.hpp +++ /dev/null @@ -1,1118 +0,0 @@ -// -// basic_datagram_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_datagram_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL) - -/// Provides datagram-oriented socket functionality. -/** - * The basic_datagram_socket class template provides asynchronous and blocking - * datagram-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_datagram_socket_ext - : public basic_socket_ext -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_datagram_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket_ext::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_datagram_socket_ext(const executor_type& ex) - : basic_socket_ext(ex) - { - } - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_datagram_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, const protocol_type& protocol) - : basic_socket_ext(ex, protocol) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, protocol) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket_ext(ex, endpoint) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, endpoint) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext(ex, protocol, native_socket) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_datagram_socket from another. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - basic_datagram_socket_ext(basic_datagram_socket_ext&& other) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from another. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - basic_datagram_socket_ext& operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - template - basic_datagram_socket_ext(basic_datagram_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_datagram_socket_ext& - >::type operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_datagram_socket_ext() - { - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code socket.send(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, buffers, flags); - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.send_to(boost::asio::buffer(data, size), destination); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send_to( - this->impl_.get_implementation(), buffers, destination, 0, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send_to( - this->impl_.get_implementation(), buffers, destination, flags, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->impl_.get_service().send_to(this->impl_.get_implementation(), - buffers, destination, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_send_to( - * boost::asio::buffer(data, size), destination, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send_to(), handler, this, buffers, - destination, socket_base::message_flags(0)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send_to(), handler, this, buffers, destination, flags); - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.receive(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, buffers, flags); - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * boost::asio::ip::udp::endpoint sender_endpoint; - * socket.receive_from( - * boost::asio::buffer(data, size), sender_endpoint); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.async_receive_from( - * boost::asio::buffer(data, size), sender_endpoint, handler); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive_from(), handler, this, buffers, - &sender_endpoint, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive_from(), handler, - this, buffers, &sender_endpoint, flags); - } - -private: - struct initiate_async_send - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_datagram_socket_ext* self, const ConstBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_send_to - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_datagram_socket_ext* self, const ConstBufferSequence& buffers, - const endpoint_type& destination, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send_to( - self->impl_.get_implementation(), buffers, destination, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_receive - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_datagram_socket_ext* self, const MutableBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_receive_from - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_datagram_socket_ext* self, const MutableBufferSequence& buffers, - endpoint_type* sender_endpoint, socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive_from( - self->impl_.get_implementation(), buffers, *sender_endpoint, flags, - handler2.value, self->impl_.get_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/basic_socket_acceptor_ext.hpp b/implementation/helper/1.74/boost/asio/basic_socket_acceptor_ext.hpp deleted file mode 100644 index 998b86d..0000000 --- a/implementation/helper/1.74/boost/asio/basic_socket_acceptor_ext.hpp +++ /dev/null @@ -1,2381 +0,0 @@ -// -// basic_socket_acceptor_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_acceptor_ext; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL) - -/// Provides the ability to accept new connections. -/** - * The basic_socket_acceptor_ext class template is used for accepting new socket - * connections. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Example - * Opening a socket acceptor with the SO_REUSEADDR option enabled: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); - * acceptor.open(endpoint.protocol()); - * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ -template -class basic_socket_acceptor_ext - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// The native representation of an acceptor. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext_local< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - */ - explicit basic_socket_acceptor_ext(const executor_type& ex) - : impl_(ex) - { - } - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - */ - template - explicit basic_socket_acceptor_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(const executor_type& ex, const protocol_type& protocol) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor acceptor(my_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ - basic_socket_acceptor_ext(const executor_type& ex, - const endpoint_type& endpoint, bool reuse_addr = true) - : impl_(ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - impl_.get_service().set_option(impl_.get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - impl_.get_service().listen(impl_.get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor acceptor(my_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const endpoint_type& endpoint, bool reuse_addr = true, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - impl_.get_service().set_option(impl_.get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - impl_.get_service().listen(impl_.get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct a basic_socket_acceptor on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_acceptor) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket_acceptor on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_acceptor, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket_acceptor from another. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket_acceptor from another. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - basic_socket_acceptor_ext& operator=(basic_socket_acceptor_ext&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All socket acceptors have access to each other's implementations. - template - friend class basic_socket_acceptor_ext; - - /// Move-construct a basic_socket_acceptor from an acceptor of another - /// protocol type. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - template - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket_acceptor from an acceptor of another protocol - /// type. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_acceptor_ext& - >::type operator=(basic_socket_acceptor_ext&& other) - { - basic_socket_acceptor_ext tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the acceptor. - /** - * This function destroys the acceptor, cancelling any outstanding - * asynchronous operations associated with the acceptor as if by calling - * @c cancel. - */ - ~basic_socket_acceptor_ext() - { - } - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * acceptor.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::system::error_code ec; - * acceptor.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_acceptor) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_acceptor, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the acceptor is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * acceptor.bind(endpoint); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * boost::system::error_code ec; - * acceptor.bind(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @throws boost::system::system_error Thrown on failure. - */ - void listen(int backlog = socket_base::max_listen_connections) - { - boost::system::error_code ec; - impl_.get_service().listen(impl_.get_implementation(), backlog, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec) - { - impl_.get_service().listen(impl_.get_implementation(), backlog, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @throws boost::system::system_error Thrown on failure. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native acceptor representation. - /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - */ - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * acceptor.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * boost::system::error_code ec; - * acceptor.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * acceptor.get_option(option); - * bool is_set = option.get(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * boost::system::error_code ec; - * acceptor.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * socket.io_control(command); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the acceptor. - /** - * @returns @c true if the acceptor's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native acceptor. This mode has no effect on the behaviour of the acceptor - * object's synchronous operations. - * - * @returns @c true if the underlying acceptor is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the acceptor object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native acceptor. - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @returns An object that represents the local endpoint of the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the acceptor. - * Returns a default-constructed endpoint object if an error occurred and the - * error handler did not throw an exception. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the acceptor to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for an acceptor to - * enter a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_wait( - * boost::asio::ip::tcp::acceptor::wait_read, - * wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * acceptor.accept(socket); - * @endcode - */ - template - void accept(basic_socket_ext_local& peer, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - impl_.get_service().accept(impl_.get_implementation(), - peer, static_cast(0), ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * acceptor.accept(socket, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID accept( - basic_socket_ext_local& peer, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - impl_.get_service().accept(impl_.get_implementation(), - peer, static_cast(0), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket. The function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * acceptor.async_accept(socket, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - return async_initiate( - initiate_async_accept(), handler, this, - &peer, static_cast(0)); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.accept(socket, endpoint); - * @endcode - */ - template - void accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint; - * boost::system::error_code ec; - * acceptor.accept(socket, endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - impl_.get_service().accept( - impl_.get_implementation(), peer, &peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket, and additionally obtain the endpoint of the remote peer. The - * function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) - { - return async_initiate( - initiate_async_accept(), handler, this, &peer, &peer_endpoint); - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - typename Protocol::socket accept() - { - boost::system::error_code ec; - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept(boost::system::error_code& ec) - { - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - return async_initiate( - initiate_async_move_accept(), handler, this, - impl_.get_executor(), static_cast(0), - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly - * accepted socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, - typename enable_if< - is_executor::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, boost::system::error_code& ec, - typename enable_if< - is_executor::value - >::type* = 0) - { - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * Executor1>::other peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(my_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - Executor1>::other)) - async_accept(const Executor1& ex, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_executor::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - Executor1>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - ex, static_cast(0), - static_cast(0)); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * typename ExecutionContext::executor_type>::other peer - * // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(my_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other)) - async_accept(ExecutionContext& context, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - context.get_executor(), static_cast(0), - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint)); - * @endcode - */ - typename Protocol::socket accept(endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept( - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - return async_initiate( - initiate_async_move_accept(), handler, this, - impl_.get_executor(), &peer_endpoint, - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint)); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, endpoint_type& peer_endpoint, - typename enable_if< - is_executor::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint)); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, endpoint_type& peer_endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const executor_type& ex, - endpoint_type& peer_endpoint, boost::system::error_code& ec, - typename enable_if< - is_executor::value - >::type* = 0) - { - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, - endpoint_type& peer_endpoint, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * Executor1>::other peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(my_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - Executor1>::other)) - async_accept(const Executor1& ex, endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_executor::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - Executor1>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - ex, &peer_endpoint, - static_cast(0)); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * typename ExecutionContext::executor_type>::other peer - * // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(my_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other)) - async_accept(ExecutionContext& context, - endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - context.get_executor(), &peer_endpoint, - static_cast(0)); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - -private: - // Disallow copying and assignment. - basic_socket_acceptor_ext(const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED; - basic_socket_acceptor_ext& operator=( - const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_acceptor_ext* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_accept - { - template - void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - basic_socket_acceptor_ext* self, basic_socket_ext_local* peer, - endpoint_type* peer_endpoint) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_accept( - self->impl_.get_implementation(), *peer, peer_endpoint, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_move_accept - { - template - void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - basic_socket_acceptor_ext* self, const Executor1& peer_ex, - endpoint_type* peer_endpoint, Socket*) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( - MoveAcceptHandler, handler, Socket) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_move_accept( - self->impl_.get_implementation(), peer_ex, peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext_local, Executor> impl_; -#endif -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/basic_socket_ext.hpp b/implementation/helper/1.74/boost/asio/basic_socket_ext.hpp deleted file mode 100644 index 523f97a..0000000 --- a/implementation/helper/1.74/boost/asio/basic_socket_ext.hpp +++ /dev/null @@ -1,1859 +0,0 @@ -// -// basic_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL) - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext(const executor_type& ex) - : impl_(ex) - { - } - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const protocol_type& protocol) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : impl_(ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const protocol_type& protocol, - const native_handle_type& native_socket) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const protocol_type& protocol, - const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext(basic_socket_ext&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext& operator=(basic_socket_ext&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket_ext; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - basic_socket_ext(basic_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_ext& - >::type operator=(basic_socket_ext && other) - { - basic_socket_ext tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return impl_.get_service().at_mark(impl_.get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = impl_.get_service().available( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return impl_.get_service().available(impl_.get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - boost::system::error_code open_ec; - if (!is_open()) - { - const protocol_type protocol = peer_endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); - } - - return async_initiate( - initiate_async_connect(), handler, this, peer_endpoint, open_ec); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().remote_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext() - { - } - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext, Executor> impl_; -#endif - -private: - // Disallow copying and assignment. - basic_socket_ext(const basic_socket_ext&) BOOST_ASIO_DELETED; - basic_socket_ext& operator=(const basic_socket_ext&) BOOST_ASIO_DELETED; - - struct initiate_async_connect - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, - basic_socket_ext* self, const endpoint_type& peer_endpoint, - const boost::system::error_code& open_ec) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (open_ec) - { - boost::asio::post(self->impl_.get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); - } - else - { - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_connect( - self->impl_.get_implementation(), peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - } - }; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_ext* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/basic_socket_ext_local.hpp b/implementation/helper/1.74/boost/asio/basic_socket_ext_local.hpp deleted file mode 100644 index 855d01c..0000000 --- a/implementation/helper/1.74/boost/asio/basic_socket_ext_local.hpp +++ /dev/null @@ -1,1859 +0,0 @@ -// -// basic_socket_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_ext_local; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL) - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext_local - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_socket_ext_local other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext_local< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext_local lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext_local(const executor_type& ex) - : impl_(ex) - { - } - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_socket_ext_local(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const endpoint_type& endpoint) - : impl_(ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol, - const native_handle_type& native_socket) - : impl_(ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol, - const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext_local(basic_socket_ext_local&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext_local& operator=(basic_socket_ext_local&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket_ext_local; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - basic_socket_ext_local(basic_socket_ext_local&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_ext_local& - >::type operator=(basic_socket_ext_local && other) - { - basic_socket_ext_local tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return impl_.get_service().at_mark(impl_.get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = impl_.get_service().available( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return impl_.get_service().available(impl_.get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - boost::system::error_code open_ec; - if (!is_open()) - { - const protocol_type protocol = peer_endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); - } - - return async_initiate( - initiate_async_connect(), handler, this, peer_endpoint, open_ec); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().remote_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext_local() - { - } - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext_local, Executor> impl_; -#endif - -private: - // Disallow copying and assignment. - basic_socket_ext_local(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - basic_socket_ext_local& operator=(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - - struct initiate_async_connect - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, - basic_socket_ext_local* self, const endpoint_type& peer_endpoint, - const boost::system::error_code& open_ec) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (open_ec) - { - boost::asio::post(self->impl_.get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); - } - else - { - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_connect( - self->impl_.get_implementation(), peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - } - }; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_ext_local* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/basic_stream_socket_ext.hpp b/implementation/helper/1.74/boost/asio/basic_stream_socket_ext.hpp deleted file mode 100644 index e77f5eb..0000000 --- a/implementation/helper/1.74/boost/asio/basic_stream_socket_ext.hpp +++ /dev/null @@ -1,996 +0,0 @@ -// -// basic_stream_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_stream_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL) - -/// Provides stream-oriented socket functionality. -/** - * The basic_stream_socket_ext class template provides asynchronous and blocking - * stream-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Concepts: - * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. - */ -template -class basic_stream_socket_ext - : public basic_socket_ext_local -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_stream_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_stream_socket without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_stream_socket_ext(const executor_type& ex) - : basic_socket_ext_local(ex) - { - } - - /// Construct a basic_stream_socket without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_stream_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context) - { - } - - /// Construct and open a basic_stream_socket. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, const protocol_type& protocol) - : basic_socket_ext_local(ex, protocol) - { - } - - /// Construct and open a basic_stream_socket. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, protocol) - { - } - - /// Construct a basic_stream_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket_ext_local(ex, endpoint) - { - } - - /// Construct a basic_stream_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, endpoint) - { - } - - /// Construct a basic_stream_socket on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext_local(ex, protocol, native_socket) - { - } - - /// Construct a basic_stream_socket on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_stream_socket from another. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - basic_stream_socket_ext(basic_stream_socket_ext&& other) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket from another. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - basic_stream_socket_ext& operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_stream_socket from a socket of another protocol - /// type. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - template - basic_stream_socket_ext(basic_stream_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket from a socket of another protocol type. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_stream_socket_ext& - >::type operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_stream_socket_ext() - { - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. Returns 0 if an error occurred. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, buffers, flags); - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. Returns 0 if an error occurred. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, buffers, flags); - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @returns The number of bytes written. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.write_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "write_some"); - return s; - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes written. Returns 0 if an error occurred. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous write. - /** - * This function is used to asynchronously write data to the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be written to the socket. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the write operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes written. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The write operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_write_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_write_some(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @returns The number of bytes read. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.read_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "read_some"); - return s; - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes read. Returns 0 if an error occurred. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous read. - /** - * This function is used to asynchronously read data from the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be read. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the read operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes read. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The read operation may not read all of the requested number of bytes. - * Consider using the @ref async_read function if you need to ensure that the - * requested amount of data is read before the asynchronous operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_read_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_read_some(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - -private: - struct initiate_async_send - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_stream_socket_ext* self, const ConstBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_receive - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_stream_socket_ext* self, const MutableBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext.hpp deleted file mode 100644 index 67fe6bd..0000000 --- a/implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext.hpp +++ /dev/null @@ -1,586 +0,0 @@ -// -// detail/handler_type_requirements_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3)), - char(0)); - -template -char (&three_arg_handler_test(Handler, ...))[2]; - -template -auto three_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3 *a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3))), - char(0)); - -template -char (&three_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - boost::asio::ip::address)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::three_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext_local.hpp deleted file mode 100644 index 65640ad..0000000 --- a/implementation/helper/1.74/boost/asio/detail/handler_type_requirements_ext_local.hpp +++ /dev/null @@ -1,588 +0,0 @@ -// -// detail/handler_type_requirements_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto four_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3, *a4)), - char(0)); - -template -char (&four_arg_handler_test(Handler, ...))[2]; - -template -auto four_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3), BOOST_ASIO_MOVE_CAST(Arg4)(*a4))), - char(0)); - -template -char (&four_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - std::uint32_t, std::uint32_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::four_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp deleted file mode 100644 index 04036ad..0000000 --- a/implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext::reactive_socket_service_base_ext( - execution_context& context) - : reactor_(use_service(context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext::base_shutdown() -{ -} - -void reactive_socket_service_base_ext::construct( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext::base_move_construct( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::base_move_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::destroy( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext::close( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext::cancel( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_open( - reactive_socket_service_base_ext::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext::start_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext::start_accept_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext::start_connect_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP diff --git a/implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp b/implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp deleted file mode 100644 index 288cf19..0000000 --- a/implementation/helper/1.74/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local( - execution_context& context) - : reactor_(use_service(context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext_local::base_shutdown() -{ -} - -void reactive_socket_service_base_ext_local::construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext_local::base_move_construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::base_move_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::destroy( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext_local::close( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext_local::cancel( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_open( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext_local::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext_local::start_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext_local::start_accept_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext_local::start_connect_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP diff --git a/implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext.ipp deleted file mode 100644 index 39e2ed8..0000000 --- a/implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext.ipp +++ /dev/null @@ -1,234 +0,0 @@ -// -// detail/impl/socket_ops_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; - LPFN_WSARECVMSG WSARecvMsg; - DWORD NumberOfBytes; - signed_size_type result; - - result = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, - &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, - &WSARecvMsg, sizeof WSARecvMsg, - &NumberOfBytes, NULL, NULL); - get_last_error(ec, true); - if (ec.value() == SOCKET_ERROR) { - WSARecvMsg = NULL; - return 0; - } - - WSABUF wsaBuf; - WSAMSG msg; - char controlBuffer[1024]; - msg.name = addr; - msg.namelen = *addrlen; - wsaBuf.buf = bufs->buf; - wsaBuf.len = bufs->len; - msg.lpBuffers = &wsaBuf; - msg.dwBufferCount = count; - msg.Control.len = sizeof controlBuffer; - msg.Control.buf = controlBuffer; - msg.dwFlags = flags; - - DWORD dwNumberOfBytesRecvd; - result = WSARecvMsg(s, &msg, &dwNumberOfBytesRecvd, NULL, NULL); - get_last_error(ec, true); - - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = WSA_CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } else { - dwNumberOfBytesRecvd = -1; - } - return dwNumberOfBytesRecvd; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - char cmbuf[0x100]; - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - msg.msg_control = cmbuf; - msg.msg_controllen = sizeof(cmbuf); - signed_size_type result = ::recvmsg(s, &msg, flags); - get_last_error(ec, true); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec.assign(0, ec.category()); - - // Find destination address - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, boost::asio::ip::address& da) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP diff --git a/implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext_local.ipp b/implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext_local.ipp deleted file mode 100644 index 83a673b..0000000 --- a/implementation/helper/1.74/boost/asio/detail/impl/socket_ops_ext_local.ipp +++ /dev/null @@ -1,307 +0,0 @@ -// -// detail/impl/socket_ops_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recv(socket_type s, buf* bufs, size_t count, - int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = ::WSARecv(s, bufs, - recv_buf_count, &bytes_transferred, &recv_flags, 0, 0); - get_last_error(ec, true); - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec.assign(0, ec.category()); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = ::recvmsg(s, &msg, flags); - get_last_error(ec, true); - if (result >= 0) { - ec.assign(0, ec.category()); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int tmp_addrlen = (int)*addrlen; - int result = ::WSARecvFrom(s, bufs, recv_buf_count, - &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0); - get_last_error(ec, true); - *addrlen = (std::size_t)tmp_addrlen; - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec.assign(0, ec.category()); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = ::recvmsg(s, &msg, flags); - get_last_error(ec, true); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec.assign(0, ec.category()); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec, uid, gid); - - // Check for end of stream. - if (is_stream && bytes == 0) - { - ec = boost::asio::error::eof; - return true; - } - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext.hpp deleted file mode 100644 index 1167d57..0000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext.hpp +++ /dev/null @@ -1,162 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recv_op_base_ext(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(success_ec, &reactive_socket_recv_op_base_ext::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext* o( - static_cast(base)); - - typedef buffer_sequence_adapter bufs_type; - - status result; - if (bufs_type::is_single_buffer) - { - result = socket_ops::non_blocking_recv1(o->socket_, - bufs_type::first(o->buffers_).data(), - bufs_type::first(o->buffers_).size(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - else - { - bufs_type bufs(o->buffers_); - result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext : - public reactive_socket_recv_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext); - - reactive_socket_recv_op_ext(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - : reactive_socket_recv_op_base_ext(success_ec, - socket, state, buffers, flags, - &reactive_socket_recv_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp deleted file mode 100644 index bedbd29..0000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp +++ /dev/null @@ -1,162 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recv_op_base_ext_local(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(success_ec, &reactive_socket_recv_op_base_ext_local::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext_local* o( - static_cast(base)); - - typedef buffer_sequence_adapter bufs_type; - - status result; - if (bufs_type::is_single_buffer) - { - result = socket_ops::non_blocking_recv1(o->socket_, - bufs_type::first(o->buffers_).data(), - bufs_type::first(o->buffers_).size(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - else - { - bufs_type bufs(o->buffers_); - result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext_local : - public reactive_socket_recv_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext_local); - - reactive_socket_recv_op_ext_local(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - : reactive_socket_recv_op_base_ext_local(success_ec, - socket, state, buffers, flags, - &reactive_socket_recv_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext_local* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3, handler.arg4)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp deleted file mode 100644 index 875fe14..0000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp +++ /dev/null @@ -1,153 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvfrom_op_base_ext(const boost::system::error_code& success_ec, - socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(success_ec, &reactive_socket_recvfrom_op_base_ext::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->da_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext : - public reactive_socket_recvfrom_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext); - - reactive_socket_recvfrom_op_ext(const boost::system::error_code& success_ec, - socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvfrom_op_base_ext( - success_ec, socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp deleted file mode 100644 index f9fef2b..0000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp +++ /dev/null @@ -1,148 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvfrom_op_base_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext_local : - public reactive_socket_recvfrom_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext_local); - - reactive_socket_recvfrom_op_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvfrom_op_base_ext_local( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp deleted file mode 100644 index bd315dc..0000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp +++ /dev/null @@ -1,144 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvmsg_op_base_ext(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvmsg_op_base_ext::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext : - public reactive_socket_recvmsg_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext); - - reactive_socket_recvmsg_op_ext(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvmsg_op_base_ext(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp deleted file mode 100644 index 8148690..0000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvmsg_op_base_ext_local(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext_local(success_ec, &reactive_socket_recvmsg_op_base_ext_local::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext_local : - public reactive_socket_recvmsg_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext_local); - - reactive_socket_recvmsg_op_ext_local(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvmsg_op_base_ext_local(success_ec, - socket, buffers, in_flags, out_flags, - &reactive_socket_recvmsg_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext.hpp deleted file mode 100644 index 2e68a87..0000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext.hpp +++ /dev/null @@ -1,524 +0,0 @@ -// -// detail/reactive_socket_service_base.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext(execution_context& context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op< - ConstBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - in_flags, out_flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; - - // Cached success value to avoid accessing category singleton. - const boost::system::error_code success_ec_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext_local.hpp deleted file mode 100644 index a71fce5..0000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_base_ext_local.hpp +++ /dev/null @@ -1,524 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext_local -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext_local(execution_context& context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op< - ConstBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext_local< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext_local< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - in_flags, out_flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; - - // Cached success value to avoid accessing category singleton. - const boost::system::error_code success_ec_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext.hpp deleted file mode 100644 index 7254ccd..0000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext.hpp +++ /dev/null @@ -1,508 +0,0 @@ -// -// detail/reactive_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext : - public execution_context_service_base >, - public reactive_socket_service_base_ext -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext(execution_context& context) - : execution_context_service_base< - reactive_socket_service_ext >(context), - reactive_socket_service_base_ext(context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext&, - typename reactive_socket_service_ext< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - destination, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(success_ec_, impl.socket_, protocol, buffers, - sender_endpoint, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_move_accept(implementation_type& impl, - const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, peer_io_ex, impl.socket_, impl.state_, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext_local.hpp deleted file mode 100644 index 8ac3265..0000000 --- a/implementation/helper/1.74/boost/asio/detail/reactive_socket_service_ext_local.hpp +++ /dev/null @@ -1,508 +0,0 @@ -// -// detail/reactive_socket_service_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext_local : - public execution_context_service_base >, - public reactive_socket_service_base_ext_local -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext_local::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext_local(execution_context& context) - : execution_context_service_base< - reactive_socket_service_ext_local >(context), - reactive_socket_service_base_ext_local(context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext_local&, - typename reactive_socket_service_ext_local< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - destination, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(success_ec_, impl.socket_, protocol, buffers, - sender_endpoint, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_move_accept(implementation_type& impl, - const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, peer_io_ex, impl.socket_, impl.state_, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/1.74/boost/asio/detail/reactor_op_ext.hpp deleted file mode 100644 index 697cd9f..0000000 --- a/implementation/helper/1.74/boost/asio/detail/reactor_op_ext.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// detail/reactor_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext - : public reactor_op -{ -public: - // The destination address - boost::asio::ip::address da_; - - reactor_op_ext(const boost::system::error_code& success_ec, - perform_func_type perform_func, func_type complete_func) - : reactor_op(success_ec, perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/reactor_op_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/reactor_op_ext_local.hpp deleted file mode 100644 index 3d9ae5f..0000000 --- a/implementation/helper/1.74/boost/asio/detail/reactor_op_ext_local.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// detail/reactor_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext_local - : public reactor_op -{ -public: - // Credentials - std::uint32_t uid_; - std::uint32_t gid_; - - reactor_op_ext_local(const boost::system::error_code& success_ec, - perform_func_type perform_func, func_type complete_func) - : reactor_op(success_ec, perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/1.74/boost/asio/detail/socket_ops_ext.hpp deleted file mode 100644 index 9285fed..0000000 --- a/implementation/helper/1.74/boost/asio/detail/socket_ops_ext.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// detail/socket_ops_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - boost::asio::ip::address& da); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - boost::asio::ip::address& da); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - boost::asio::ip::address& da); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/1.74/boost/asio/detail/socket_ops_ext_local.hpp b/implementation/helper/1.74/boost/asio/detail/socket_ops_ext_local.hpp deleted file mode 100644 index a937bb6..0000000 --- a/implementation/helper/1.74/boost/asio/detail/socket_ops_ext_local.hpp +++ /dev/null @@ -1,95 +0,0 @@ -// -// detail/socket_ops_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recv(socket_type s, buf* bufs, - size_t count, int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recv(socket_type s, state_type state, buf* bufs, - size_t count, int flags, bool all_empty, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recv(state_type state, - const weak_cancel_token_type& cancel_token, bool all_empty, - boost::system::error_code& ec, size_t bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.74/boost/asio/ip/udp_ext.hpp b/implementation/helper/1.74/boost/asio/ip/udp_ext.hpp deleted file mode 100644 index 6ce2ac4..0000000 --- a/implementation/helper/1.74/boost/asio/ip/udp_ext.hpp +++ /dev/null @@ -1,115 +0,0 @@ -// -// ip/udp_ext.hpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_IP_UDP_EXT_HPP -#define BOOST_ASIO_IP_UDP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace ip { - -/// Encapsulates the flags needed for UDP. -/** - * The boost::asio::ip::udp_ext class contains flags necessary for UDP sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol, InternetProtocol. - */ -class udp_ext -{ -public: - /// The type of a UDP endpoint. - typedef basic_endpoint endpoint; - - /// Construct to represent the IPv4 UDP protocol. - static udp_ext v4() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET)); - } - - /// Construct to represent the IPv6 UDP protocol. - static udp_ext v6() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET6)); - } - - /// Obtain an identifier for the type of the protocol. - int type() const - { - return BOOST_ASIO_OS_DEF(SOCK_DGRAM); - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return BOOST_ASIO_OS_DEF(IPPROTO_UDP); - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return family_; - } - - /// The UDP socket type. - typedef basic_datagram_socket_ext socket; - - /// The UDP resolver type. - typedef basic_resolver resolver; - - /// Compare two protocols for equality. - friend bool operator==(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ == p2.family_; - } - - /// Compare two protocols for inequality. - friend bool operator!=(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ != p2.family_; - } - -private: - // Construct with a specific family. - explicit udp_ext(int protocol_family) - : family_(protocol_family) - { - } - - int family_; -}; - -} // namespace ip -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_IP_UDP_EXT_HPP diff --git a/implementation/helper/1.74/boost/asio/local/stream_protocol_ext.hpp b/implementation/helper/1.74/boost/asio/local/stream_protocol_ext.hpp deleted file mode 100644 index 7c57c62..0000000 --- a/implementation/helper/1.74/boost/asio/local/stream_protocol_ext.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// local/stream_protocol_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP -#define BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ - || defined(GENERATING_DOCUMENTATION) - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace local { - -/// Encapsulates the flags needed for stream-oriented UNIX sockets. -/** - * The boost::asio::local::stream_protocol class contains flags necessary for - * stream-oriented UNIX domain sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol. - */ -class stream_protocol_ext -{ -public: - /// Obtain an identifier for the type of the protocol. - int type() const - { - return SOCK_STREAM; - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return 0; - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return AF_UNIX; - } - - /// The type of a UNIX domain endpoint. - typedef basic_endpoint endpoint; - - /// The UNIX domain socket type. - typedef basic_stream_socket_ext socket; - - /// The UNIX domain acceptor type. - typedef basic_socket_acceptor_ext acceptor; - -#if !defined(BOOST_ASIO_NO_IOSTREAM) - /// The UNIX domain iostream type. - typedef basic_socket_iostream iostream; -#endif // !defined(BOOST_ASIO_NO_IOSTREAM) -}; - -} // namespace local -} // namespace asio -} // namespace boost - -#include - -#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) - // || defined(GENERATING_DOCUMENTATION) - -#endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/1.76/boost/asio/basic_datagram_socket_ext.hpp deleted file mode 100644 index 49a4950..0000000 --- a/implementation/helper/1.76/boost/asio/basic_datagram_socket_ext.hpp +++ /dev/null @@ -1,1118 +0,0 @@ -// -// basic_datagram_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_datagram_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_FWD_DECL) - -/// Provides datagram-oriented socket functionality. -/** - * The basic_datagram_socket class template provides asynchronous and blocking - * datagram-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_datagram_socket_ext - : public basic_socket_ext -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_datagram_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket_ext::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_datagram_socket_ext(const executor_type& ex) - : basic_socket_ext(ex) - { - } - - /// Construct a basic_datagram_socket without opening it. - /** - * This constructor creates a datagram socket without opening it. The open() - * function must be called before data can be sent or received on the socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_datagram_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, const protocol_type& protocol) - : basic_socket_ext(ex, protocol) - { - } - - /// Construct and open a basic_datagram_socket. - /** - * This constructor creates and opens a datagram socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, protocol) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket_ext(ex, endpoint) - { - } - - /// Construct a basic_datagram_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a datagram socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the datagram - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, endpoint) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_datagram_socket_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext(ex, protocol, native_socket) - { - } - - /// Construct a basic_datagram_socket on an existing native socket. - /** - * This constructor creates a datagram socket object to hold an existing - * native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_datagram_socket_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext(context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_datagram_socket from another. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - basic_datagram_socket_ext(basic_datagram_socket_ext&& other) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from another. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - basic_datagram_socket_ext& operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This constructor moves a datagram socket from one object to another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - template - basic_datagram_socket_ext(basic_datagram_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : basic_socket_ext(std::move(other)) - { - } - - /// Move-assign a basic_datagram_socket from a socket of another protocol - /// type. - /** - * This assignment operator moves a datagram socket from one object to - * another. - * - * @param other The other basic_datagram_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_datagram_socket(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_datagram_socket_ext& - >::type operator=(basic_datagram_socket_ext&& other) - { - basic_socket_ext::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_datagram_socket_ext() - { - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code socket.send(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One ore more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on a connected socket. - /** - * This function is used to send data on the datagram socket. The function - * call will block until the data has been sent successfully or an error - * occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - * - * @note The send operation can only be used with a connected socket. Use - * the send_to function to send data on an unconnected datagram socket. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous send on a connected socket. - /** - * This function is used to asynchronously send data on the datagram socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_send operation can only be used with a connected socket. - * Use the async_send_to function to send data on an unconnected datagram - * socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, buffers, flags); - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.send_to(boost::asio::buffer(data, size), destination); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send_to( - this->impl_.get_implementation(), buffers, destination, 0, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send_to( - this->impl_.get_implementation(), buffers, destination, flags, ec); - boost::asio::detail::throw_error(ec, "send_to"); - return s; - } - - /// Send a datagram to the specified endpoint. - /** - * This function is used to send a datagram to the specified remote endpoint. - * The function call will block until the data has been sent successfully or - * an error occurs. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * - * @param destination The remote endpoint to which the data will be sent. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. - */ - template - std::size_t send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->impl_.get_service().send_to(this->impl_.get_implementation(), - buffers, destination, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * boost::asio::ip::udp::endpoint destination( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_send_to( - * boost::asio::buffer(data, size), destination, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send_to(), handler, this, buffers, - destination, socket_base::message_flags(0)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send a datagram to the specified - * remote endpoint. The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent to the remote endpoint. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param destination The remote endpoint to which the data will be sent. - * Copies will be made of the endpoint as required. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send_to(const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send_to(), handler, this, buffers, destination, flags); - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.receive(boost::asio::buffer(data, size)); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the datagram socket. The function - * call will block until data has been received successfully or an error - * occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - * - * @note The receive operation can only be used with a connected socket. Use - * the receive_from function to receive data on an unconnected datagram - * socket. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive on a connected socket. - /** - * This function is used to asynchronously receive data from the datagram - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The async_receive operation can only be used with a connected socket. - * Use the async_receive_from function to receive data on an unconnected - * datagram socket. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, buffers, flags); - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * boost::asio::ip::udp::endpoint sender_endpoint; - * socket.receive_from( - * boost::asio::buffer(data, size), sender_endpoint); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, 0, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); - boost::asio::detail::throw_error(ec, "receive_from"); - return s; - } - - /// Receive a datagram with the endpoint of the sender. - /** - * This function is used to receive a datagram. The function call will block - * until data has been received successfully or an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. - */ - template - std::size_t receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - return this->impl_.get_service().receive_from( - this->impl_.get_implementation(), buffers, sender_endpoint, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code socket.async_receive_from( - * boost::asio::buffer(data, size), sender_endpoint, handler); @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive_from(), handler, this, buffers, - &sender_endpoint, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive a datagram. The function - * call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param sender_endpoint An endpoint object that receives the endpoint of - * the remote sender of the datagram. Ownership of the sender_endpoint object - * is retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, boost::asio::ip::address)) - async_receive_from(const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive_from(), handler, - this, buffers, &sender_endpoint, flags); - } - -private: - struct initiate_async_send - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_datagram_socket_ext* self, const ConstBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_send_to - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_datagram_socket_ext* self, const ConstBufferSequence& buffers, - const endpoint_type& destination, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send_to( - self->impl_.get_implementation(), buffers, destination, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_receive - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_datagram_socket_ext* self, const MutableBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_receive_from - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_datagram_socket_ext* self, const MutableBufferSequence& buffers, - endpoint_type* sender_endpoint, socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive_from( - self->impl_.get_implementation(), buffers, *sender_endpoint, flags, - handler2.value, self->impl_.get_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/basic_socket_acceptor_ext.hpp b/implementation/helper/1.76/boost/asio/basic_socket_acceptor_ext.hpp deleted file mode 100644 index 0a86539..0000000 --- a/implementation/helper/1.76/boost/asio/basic_socket_acceptor_ext.hpp +++ /dev/null @@ -1,2381 +0,0 @@ -// -// basic_socket_acceptor_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_acceptor_ext; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_FWD_DECL) - -/// Provides the ability to accept new connections. -/** - * The basic_socket_acceptor_ext class template is used for accepting new socket - * connections. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Example - * Opening a socket acceptor with the SO_REUSEADDR option enabled: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); - * acceptor.open(endpoint.protocol()); - * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ -template -class basic_socket_acceptor_ext - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// The native representation of an acceptor. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext_local< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - */ - explicit basic_socket_acceptor_ext(const executor_type& ex) - : impl_(0, ex) - { - } - - /// Construct an acceptor without opening it. - /** - * This constructor creates an acceptor without opening it to listen for new - * connections. The open() function must be called before the acceptor can - * accept new socket connections. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - */ - template - explicit basic_socket_acceptor_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(const executor_type& ex, const protocol_type& protocol) - : impl_(0, ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an open acceptor. - /** - * This constructor creates an acceptor and automatically opens it. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor acceptor(my_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ - basic_socket_acceptor_ext(const executor_type& ex, - const endpoint_type& endpoint, bool reuse_addr = true) - : impl_(0, ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - impl_.get_service().set_option(impl_.get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - impl_.get_service().listen(impl_.get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct an acceptor opened on the given endpoint. - /** - * This constructor creates an acceptor and automatically opens it to listen - * for new connections on the specified endpoint. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param endpoint An endpoint on the local machine on which the acceptor - * will listen for new connections. - * - * @param reuse_addr Whether the constructor should set the socket option - * socket_base::reuse_address. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This constructor is equivalent to the following code: - * @code - * basic_socket_acceptor acceptor(my_context); - * acceptor.open(endpoint.protocol()); - * if (reuse_addr) - * acceptor.set_option(socket_base::reuse_address(true)); - * acceptor.bind(endpoint); - * acceptor.listen(); - * @endcode - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const endpoint_type& endpoint, bool reuse_addr = true, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - if (reuse_addr) - { - impl_.get_service().set_option(impl_.get_implementation(), - socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - impl_.get_service().listen(impl_.get_implementation(), - socket_base::max_listen_connections, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Construct a basic_socket_acceptor on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param ex The I/O executor that the acceptor will use, by default, to - * dispatch handlers for any asynchronous operations performed on the - * acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_acceptor_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_acceptor) - : impl_(0, ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket_acceptor on an existing native acceptor. - /** - * This constructor creates an acceptor object to hold an existing native - * acceptor. - * - * @param context An execution context which provides the I/O executor that - * the acceptor will use, by default, to dispatch handlers for any - * asynchronous operations performed on the acceptor. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_acceptor_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_acceptor, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket_acceptor from another. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket_acceptor from another. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - basic_socket_acceptor_ext& operator=(basic_socket_acceptor_ext&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All socket acceptors have access to each other's implementations. - template - friend class basic_socket_acceptor_ext; - - /// Move-construct a basic_socket_acceptor from an acceptor of another - /// protocol type. - /** - * This constructor moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - template - basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket_acceptor from an acceptor of another protocol - /// type. - /** - * This assignment operator moves an acceptor from one object to another. - * - * @param other The other basic_socket_acceptor object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket_acceptor(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_acceptor_ext& - >::type operator=(basic_socket_acceptor_ext&& other) - { - basic_socket_acceptor_ext tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the acceptor. - /** - * This function destroys the acceptor, cancelling any outstanding - * asynchronous operations associated with the acceptor as if by calling - * @c cancel. - */ - ~basic_socket_acceptor_ext() - { - } - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * acceptor.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the acceptor using the specified protocol. - /** - * This function opens the socket acceptor so that it will use the specified - * protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::system::error_code ec; - * acceptor.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_acceptor) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assigns an existing native acceptor to the acceptor. - /* - * This function opens the acceptor to hold an existing native acceptor. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_acceptor A native acceptor. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_acceptor, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_acceptor, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the acceptor is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * acceptor.bind(endpoint); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the acceptor to the given local endpoint. - /** - * This function binds the socket acceptor to the specified endpoint on the - * local machine. - * - * @param endpoint An endpoint on the local machine to which the socket - * acceptor will be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); - * acceptor.open(endpoint.protocol()); - * boost::system::error_code ec; - * acceptor.bind(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @throws boost::system::system_error Thrown on failure. - */ - void listen(int backlog = socket_base::max_listen_connections) - { - boost::system::error_code ec; - impl_.get_service().listen(impl_.get_implementation(), backlog, ec); - boost::asio::detail::throw_error(ec, "listen"); - } - - /// Place the acceptor into the state where it will listen for new - /// connections. - /** - * This function puts the socket acceptor into the state where it may accept - * new connections. - * - * @param backlog The maximum length of the queue of pending connections. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.listen(boost::asio::socket_base::max_listen_connections, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID listen(int backlog, boost::system::error_code& ec) - { - impl_.get_service().listen(impl_.get_implementation(), backlog, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @throws boost::system::system_error Thrown on failure. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the acceptor. - /** - * This function is used to close the acceptor. Any asynchronous accept - * operations will be cancelled immediately. - * - * A subsequent call to open() is required before the acceptor can again be - * used to again perform socket accept operations. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native acceptor. - /** - * This function causes all outstanding asynchronous accept operations to - * finish immediately, and the handlers for cancelled operations will be - * passed the boost::asio::error::operation_aborted error. Ownership of the - * native acceptor is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native acceptor representation. - /** - * This function may be used to obtain the underlying representation of the - * acceptor. This is intended to allow access to native acceptor functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - */ - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the acceptor. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * acceptor.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the acceptor. - /** - * This function is used to set an option on the acceptor. - * - * @param option The new option value to be set on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::reuse_address - * boost::asio::socket_base::enable_connection_aborted - * - * @par Example - * Setting the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option(true); - * boost::system::error_code ec; - * acceptor.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * acceptor.get_option(option); - * bool is_set = option.get(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the acceptor. - /** - * This function is used to get the current value of an option on the - * acceptor. - * - * @param option The option value to be obtained from the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::reuse_address - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::reuse_address option; - * boost::system::error_code ec; - * acceptor.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * socket.io_control(command); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the acceptor. - /** - * This function is used to execute an IO control command on the acceptor. - * - * @param command The IO control command to be performed on the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the acceptor. - /** - * @returns @c true if the acceptor's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the acceptor. - /** - * @param mode If @c true, the acceptor's synchronous operations will fail - * with boost::asio::error::would_block if they are unable to perform the - * requested operation immediately. If @c false, synchronous operations will - * block until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native acceptor. This mode has no effect on the behaviour of the acceptor - * object's synchronous operations. - * - * @returns @c true if the underlying acceptor is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the acceptor object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native acceptor. - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native acceptor implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native acceptor. It has no effect on the behaviour of the acceptor object's - * synchronous operations. - * - * @param mode If @c true, the underlying acceptor is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @returns An object that represents the local endpoint of the acceptor. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the acceptor. - /** - * This function is used to obtain the locally bound endpoint of the acceptor. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the acceptor. - * Returns a default-constructed endpoint object if an error occurred and the - * error handler did not throw an exception. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the acceptor to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for an acceptor to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for an acceptor to become readable. - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::system::error_code ec; - * acceptor.wait(boost::asio::ip::tcp::acceptor::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the acceptor to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for an acceptor to - * enter a ready to read, write or error condition state. - * - * @param w Specifies the desired acceptor state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_wait( - * boost::asio::ip::tcp::acceptor::wait_read, - * wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * acceptor.accept(socket); - * @endcode - */ - template - void accept(basic_socket_ext_local& peer, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - impl_.get_service().accept(impl_.get_implementation(), - peer, static_cast(0), ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer into the - * given socket. The function call will block until a new connection has been - * accepted successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * acceptor.accept(socket, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID accept( - basic_socket_ext_local& peer, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - impl_.get_service().accept(impl_.get_implementation(), - peer, static_cast(0), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket. The function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * acceptor.async_accept(socket, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - return async_initiate( - initiate_async_accept(), handler, this, - &peer, static_cast(0)); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.accept(socket, endpoint); - * @endcode - */ - template - void accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - } - - /// Accept a new connection and obtain the endpoint of the peer - /** - * This function is used to accept a new connection from a peer into the - * given socket, and additionally provide the endpoint of the remote peer. - * The function call will block until a new connection has been accepted - * successfully or an error occurs. - * - * @param peer The socket into which the new connection will be accepted. - * - * @param peer_endpoint An endpoint object which will receive the endpoint of - * the remote peer. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint; - * boost::system::error_code ec; - * acceptor.accept(socket, endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - impl_.get_service().accept( - impl_.get_implementation(), peer, &peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection into a - * socket, and additionally obtain the endpoint of the remote peer. The - * function call always returns immediately. - * - * @param peer The socket into which the new connection will be accepted. - * Ownership of the peer object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, - void (boost::system::error_code)) - async_accept(basic_socket_ext_local& peer, - endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) - { - return async_initiate( - initiate_async_accept(), handler, this, &peer, &peer_endpoint); - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - typename Protocol::socket accept() - { - boost::system::error_code ec; - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept(boost::system::error_code& ec) - { - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - return async_initiate( - initiate_async_move_accept(), handler, this, - impl_.get_executor(), static_cast(0), - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly - * accepted socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, - typename enable_if< - is_executor::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept()); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, boost::system::error_code& ec, - typename enable_if< - is_executor::value - >::type* = 0) - { - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::socket socket(acceptor.accept(my_context2, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), peer, 0, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * Executor1>::other peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(my_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - Executor1>::other)) - async_accept(const Executor1& ex, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_executor::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - Executor1>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - ex, static_cast(0), - static_cast(0)); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * typename ExecutionContext::executor_type>::other peer - * // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * acceptor.async_accept(my_context2, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other)) - async_accept(ExecutionContext& context, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - context.get_executor(), static_cast(0), - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint)); - * @endcode - */ - typename Protocol::socket accept(endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket(acceptor.accept(endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - typename Protocol::socket accept( - endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - typename Protocol::socket peer(impl_.get_executor()); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, typename Protocol::socket)) - async_accept(endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler) - { - return async_initiate( - initiate_async_move_accept(), handler, this, - impl_.get_executor(), &peer_endpoint, - static_cast(0)); - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint)); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const Executor1& ex, endpoint_type& peer_endpoint, - typename enable_if< - is_executor::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @returns A socket object representing the newly accepted connection. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint)); - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, endpoint_type& peer_endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - { - boost::system::error_code ec; - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "accept"); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor::other - accept(const executor_type& ex, - endpoint_type& peer_endpoint, boost::system::error_code& ec, - typename enable_if< - is_executor::value - >::type* = 0) - { - typename Protocol::socket::template - rebind_executor::other peer(ex); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Accept a new connection. - /** - * This function is used to accept a new connection from a peer. The function - * call will block until a new connection has been accepted successfully or - * an error occurs. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns On success, a socket object representing the newly accepted - * connection. On error, a socket object where is_open() is false. - * - * @par Example - * @code - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * boost::asio::ip::tcp::socket socket( - * acceptor.accept(my_context2, endpoint, ec)); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other - accept(ExecutionContext& context, - endpoint_type& peer_endpoint, boost::system::error_code& ec, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other peer(context); - impl_.get_service().accept(impl_.get_implementation(), - peer, &peer_endpoint, ec); - return peer; - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param ex The I/O executor object to be used for the newly accepted - * socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * Executor1>::other peer // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(my_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - Executor1>::other)) - async_accept(const Executor1& ex, endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_executor::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - Executor1>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - ex, &peer_endpoint, - static_cast(0)); - } - - /// Start an asynchronous accept. - /** - * This function is used to asynchronously accept a new connection. The - * function call always returns immediately. - * - * This overload requires that the Protocol template parameter satisfy the - * AcceptableProtocol type requirements. - * - * @param context The I/O execution context object to be used for the newly - * accepted socket. - * - * @param peer_endpoint An endpoint object into which the endpoint of the - * remote peer will be written. Ownership of the peer_endpoint object is - * retained by the caller, which must guarantee that it is valid until the - * handler is called. - * - * @param handler The handler to be called when the accept operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * typename Protocol::socket::template rebind_executor< - * typename ExecutionContext::executor_type>::other peer - * // On success, the newly accepted socket. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void accept_handler(const boost::system::error_code& error, - * boost::asio::ip::tcp::socket peer) - * { - * if (!error) - * { - * // Accept succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::acceptor acceptor(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint; - * acceptor.async_accept(my_context2, endpoint, accept_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(MoveAcceptHandler, - void (boost::system::error_code, - typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other)) - async_accept(ExecutionContext& context, - endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - typename enable_if< - is_convertible::value - >::type* = 0) - { - typedef typename Protocol::socket::template rebind_executor< - typename ExecutionContext::executor_type>::other other_socket_type; - - return async_initiate( - initiate_async_move_accept(), handler, this, - context.get_executor(), &peer_endpoint, - static_cast(0)); - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - -private: - // Disallow copying and assignment. - basic_socket_acceptor_ext(const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED; - basic_socket_acceptor_ext& operator=( - const basic_socket_acceptor_ext&) BOOST_ASIO_DELETED; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_acceptor_ext* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; - - struct initiate_async_accept - { - template - void operator()(BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, - basic_socket_acceptor_ext* self, basic_socket_ext_local* peer, - endpoint_type* peer_endpoint) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a AcceptHandler. - BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_accept( - self->impl_.get_implementation(), *peer, peer_endpoint, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_move_accept - { - template - void operator()(BOOST_ASIO_MOVE_ARG(MoveAcceptHandler) handler, - basic_socket_acceptor_ext* self, const Executor1& peer_ex, - endpoint_type* peer_endpoint, Socket*) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a MoveAcceptHandler. - BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( - MoveAcceptHandler, handler, Socket) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_move_accept( - self->impl_.get_implementation(), peer_ex, peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - }; - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext_local, Executor> impl_; -#endif -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/basic_socket_ext.hpp b/implementation/helper/1.76/boost/asio/basic_socket_ext.hpp deleted file mode 100644 index 777a0bf..0000000 --- a/implementation/helper/1.76/boost/asio/basic_socket_ext.hpp +++ /dev/null @@ -1,1859 +0,0 @@ -// -// basic_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_FWD_DECL) - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext(const executor_type& ex) - : impl_(0, ex) - { - } - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const protocol_type& protocol) - : impl_(0, ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : impl_(0, ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext(const executor_type& ex, const protocol_type& protocol, - const native_handle_type& native_socket) - : impl_(0, ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext(ExecutionContext& context, const protocol_type& protocol, - const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext(basic_socket_ext&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext& operator=(basic_socket_ext&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket_ext; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - basic_socket_ext(basic_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_ext& - >::type operator=(basic_socket_ext && other) - { - basic_socket_ext tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return impl_.get_service().at_mark(impl_.get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = impl_.get_service().available( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return impl_.get_service().available(impl_.get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - boost::system::error_code open_ec; - if (!is_open()) - { - const protocol_type protocol = peer_endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); - } - - return async_initiate( - initiate_async_connect(), handler, this, peer_endpoint, open_ec); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().remote_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext() - { - } - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext, Executor> impl_; -#endif - -private: - // Disallow copying and assignment. - basic_socket_ext(const basic_socket_ext&) BOOST_ASIO_DELETED; - basic_socket_ext& operator=(const basic_socket_ext&) BOOST_ASIO_DELETED; - - struct initiate_async_connect - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, - basic_socket_ext* self, const endpoint_type& peer_endpoint, - const boost::system::error_code& open_ec) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (open_ec) - { - boost::asio::post(self->impl_.get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); - } - else - { - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_connect( - self->impl_.get_implementation(), peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - } - }; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_ext* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/basic_socket_ext_local.hpp b/implementation/helper/1.76/boost/asio/basic_socket_ext_local.hpp deleted file mode 100644 index 2c898fc..0000000 --- a/implementation/helper/1.76/boost/asio/basic_socket_ext_local.hpp +++ /dev/null @@ -1,1859 +0,0 @@ -// -// basic_socket_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2018,2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) -# include -#elif defined(BOOST_ASIO_HAS_IOCP) -# include -#else -# include -#endif - -#if defined(BOOST_ASIO_HAS_MOVE) -# include -#endif // defined(BOOST_ASIO_HAS_MOVE) - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL) -#define BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_socket_ext_local; - -#endif // !defined(BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_FWD_DECL) - -/// Provides socket functionality. -/** - * The basic_socket class template provides functionality that is common to both - * stream-oriented and datagram-oriented sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - */ -template -class basic_socket_ext_local - : public socket_base -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_socket_ext_local other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#elif defined(BOOST_ASIO_WINDOWS_RUNTIME) - typedef typename detail::null_socket_service< - Protocol>::native_handle_type native_handle_type; -#elif defined(BOOST_ASIO_HAS_IOCP) - typedef typename detail::win_iocp_socket_service< - Protocol>::native_handle_type native_handle_type; -#else - typedef typename detail::reactive_socket_service_ext_local< - Protocol>::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// A basic_socket is always the lowest layer. - typedef basic_socket_ext_local lowest_layer_type; -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_socket_ext_local(const executor_type& ex) - : impl_(0, ex) - { - } - - /// Construct a basic_socket without opening it. - /** - * This constructor creates a socket without opening it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_socket_ext_local(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol) - : impl_(0, ex) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct and open a basic_socket. - /** - * This constructor creates and opens a socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const endpoint_type& endpoint) - : impl_(0, ex) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket, opening it and binding it to the given local - /// endpoint. - /** - * This constructor creates a socket and automatically opens it bound to the - * specified endpoint on the local machine. The protocol used is the protocol - * associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - const protocol_type protocol = endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_socket_ext_local(const executor_type& ex, const protocol_type& protocol, - const native_handle_type& native_socket) - : impl_(0, ex) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Construct a basic_socket on an existing native socket. - /** - * This constructor creates a socket object to hold an existing native socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_socket_ext_local(ExecutionContext& context, const protocol_type& protocol, - const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : impl_(0, 0, context) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_socket from another. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext_local(basic_socket_ext_local&& other) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from another. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - basic_socket_ext_local& operator=(basic_socket_ext_local&& other) - { - impl_ = std::move(other.impl_); - return *this; - } - - // All sockets have access to each other's implementations. - template - friend class basic_socket_ext_local; - - /// Move-construct a basic_socket from a socket of another protocol type. - /** - * This constructor moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - basic_socket_ext_local(basic_socket_ext_local&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : impl_(std::move(other.impl_)) - { - } - - /// Move-assign a basic_socket from a socket of another protocol type. - /** - * This assignment operator moves a socket from one object to another. - * - * @param other The other basic_socket object from which the move will - * occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_socket(const executor_type&) constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_socket_ext_local& - >::type operator=(basic_socket_ext_local && other) - { - basic_socket_ext_local tmp(std::move(other)); - impl_ = std::move(tmp.impl_); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Get the executor associated with the object. - executor_type get_executor() BOOST_ASIO_NOEXCEPT - { - return impl_.get_executor(); - } - -#if !defined(BOOST_ASIO_NO_EXTENSIONS) - /// Get a reference to the lowest layer. - /** - * This function returns a reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A reference to the lowest layer in the stack of layers. Ownership - * is not transferred to the caller. - */ - lowest_layer_type& lowest_layer() - { - return *this; - } - - /// Get a const reference to the lowest layer. - /** - * This function returns a const reference to the lowest layer in a stack of - * layers. Since a basic_socket cannot contain any further layers, it simply - * returns a reference to itself. - * - * @return A const reference to the lowest layer in the stack of layers. - * Ownership is not transferred to the caller. - */ - const lowest_layer_type& lowest_layer() const - { - return *this; - } -#endif // !defined(BOOST_ASIO_NO_EXTENSIONS) - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * @endcode - */ - void open(const protocol_type& protocol = protocol_type()) - { - boost::system::error_code ec; - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - boost::asio::detail::throw_error(ec, "open"); - } - - /// Open the socket using the specified protocol. - /** - * This function opens the socket so that it will use the specified protocol. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::system::error_code ec; - * socket.open(boost::asio::ip::tcp::v4(), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID open(const protocol_type& protocol, - boost::system::error_code& ec) - { - impl_.get_service().open(impl_.get_implementation(), protocol, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @throws boost::system::system_error Thrown on failure. - */ - void assign(const protocol_type& protocol, - const native_handle_type& native_socket) - { - boost::system::error_code ec; - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - boost::asio::detail::throw_error(ec, "assign"); - } - - /// Assign an existing native socket to the socket. - /* - * This function opens the socket to hold an existing native socket. - * - * @param protocol An object specifying which protocol is to be used. - * - * @param native_socket A native socket. - * - * @param ec Set to indicate what error occurred, if any. - */ - BOOST_ASIO_SYNC_OP_VOID assign(const protocol_type& protocol, - const native_handle_type& native_socket, boost::system::error_code& ec) - { - impl_.get_service().assign(impl_.get_implementation(), - protocol, native_socket, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is open. - bool is_open() const - { - return impl_.get_service().is_open(impl_.get_implementation()); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - void close() - { - boost::system::error_code ec; - impl_.get_service().close(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "close"); - } - - /// Close the socket. - /** - * This function is used to close the socket. Any asynchronous send, receive - * or connect operations will be cancelled immediately, and will complete - * with the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. Note that, even if - * the function indicates an error, the underlying descriptor is closed. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.close(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - * - * @note For portable behaviour with respect to graceful closure of a - * connected socket, call shutdown() before closing the socket. - */ - BOOST_ASIO_SYNC_OP_VOID close(boost::system::error_code& ec) - { - impl_.get_service().close(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release() - { - boost::system::error_code ec; - native_handle_type s = impl_.get_service().release( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "release"); - return s; - } - - /// Release ownership of the underlying native socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. Ownership - * of the native socket is then transferred to the caller. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note This function is unsupported on Windows versions prior to Windows - * 8.1, and will fail with boost::asio::error::operation_not_supported on - * these platforms. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603) - __declspec(deprecated("This function always fails with " - "operation_not_supported when used on Windows versions " - "prior to Windows 8.1.")) -#endif - native_handle_type release(boost::system::error_code& ec) - { - return impl_.get_service().release(impl_.get_implementation(), ec); - } - - /// Get the native socket representation. - /** - * This function may be used to obtain the underlying representation of the - * socket. This is intended to allow access to native socket functionality - * that is not otherwise provided. - */ - native_handle_type native_handle() - { - return impl_.get_service().native_handle(impl_.get_implementation()); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - void cancel() - { - boost::system::error_code ec; - impl_.get_service().cancel(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "cancel"); - } - - /// Cancel all asynchronous operations associated with the socket. - /** - * This function causes all outstanding asynchronous connect, send and receive - * operations to finish immediately, and the handlers for cancelled operations - * will be passed the boost::asio::error::operation_aborted error. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note Calls to cancel() will always fail with - * boost::asio::error::operation_not_supported when run on Windows XP, Windows - * Server 2003, and earlier versions of Windows, unless - * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has - * two issues that should be considered before enabling its use: - * - * @li It will only cancel asynchronous operations that were initiated in the - * current thread. - * - * @li It can appear to complete without error, but the request to cancel the - * unfinished operations may be silently ignored by the operating system. - * Whether it works or not seems to depend on the drivers that are installed. - * - * For portable cancellation, consider using one of the following - * alternatives: - * - * @li Disable asio's I/O completion port backend by defining - * BOOST_ASIO_DISABLE_IOCP. - * - * @li Use the close() function to simultaneously cancel the outstanding - * operations and close the socket. - * - * When running on Windows Vista, Windows Server 2008, and later, the - * CancelIoEx function is always used. This function does not have the - * problems described above. - */ -#if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ - && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ - && !defined(BOOST_ASIO_ENABLE_CANCELIO) - __declspec(deprecated("By default, this function always fails with " - "operation_not_supported when used on Windows XP, Windows Server 2003, " - "or earlier. Consult documentation for details.")) -#endif - BOOST_ASIO_SYNC_OP_VOID cancel(boost::system::error_code& ec) - { - impl_.get_service().cancel(impl_.get_implementation(), ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - * - * @throws boost::system::system_error Thrown on failure. - */ - bool at_mark() const - { - boost::system::error_code ec; - bool b = impl_.get_service().at_mark(impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "at_mark"); - return b; - } - - /// Determine whether the socket is at the out-of-band data mark. - /** - * This function is used to check whether the socket input is currently - * positioned at the out-of-band data mark. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return A bool indicating whether the socket is at the out-of-band data - * mark. - */ - bool at_mark(boost::system::error_code& ec) const - { - return impl_.get_service().at_mark(impl_.get_implementation(), ec); - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - * - * @throws boost::system::system_error Thrown on failure. - */ - std::size_t available() const - { - boost::system::error_code ec; - std::size_t s = impl_.get_service().available( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "available"); - return s; - } - - /// Determine the number of bytes available for reading. - /** - * This function is used to determine the number of bytes that may be read - * without blocking. - * - * @param ec Set to indicate what error occurred, if any. - * - * @return The number of bytes that may be read without blocking, or 0 if an - * error occurs. - */ - std::size_t available(boost::system::error_code& ec) const - { - return impl_.get_service().available(impl_.get_implementation(), ec); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345)); - * @endcode - */ - void bind(const endpoint_type& endpoint) - { - boost::system::error_code ec; - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - boost::asio::detail::throw_error(ec, "bind"); - } - - /// Bind the socket to the given local endpoint. - /** - * This function binds the socket to the specified endpoint on the local - * machine. - * - * @param endpoint An endpoint on the local machine to which the socket will - * be bound. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * socket.open(boost::asio::ip::tcp::v4()); - * boost::system::error_code ec; - * socket.bind(boost::asio::ip::tcp::endpoint( - * boost::asio::ip::tcp::v4(), 12345), ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID bind(const endpoint_type& endpoint, - boost::system::error_code& ec) - { - impl_.get_service().bind(impl_.get_implementation(), endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.connect(endpoint); - * @endcode - */ - void connect(const endpoint_type& peer_endpoint) - { - boost::system::error_code ec; - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - boost::asio::detail::throw_error(ec, "connect"); - } - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - boost::asio::detail::throw_error(ec, "connect"); - } - - /// Connect the socket to the specified endpoint. - /** - * This function is used to connect a socket to the specified remote endpoint. - * The function call will block until the connection is successfully made or - * an error occurs. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * boost::system::error_code ec; - * socket.connect(endpoint, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID connect(const endpoint_type& peer_endpoint, - boost::system::error_code& ec) - { - if (!is_open()) - { - impl_.get_service().open(impl_.get_implementation(), - peer_endpoint.protocol(), ec); - if (ec) - { - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - } - - impl_.get_service().connect(impl_.get_implementation(), peer_endpoint, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Start an asynchronous connect. - /** - * This function is used to asynchronously connect a socket to the specified - * remote endpoint. The function call always returns immediately. - * - * The socket is automatically opened if it is not already open. If the - * connect fails, and the socket was automatically opened, the socket is - * not returned to the closed state. - * - * @param peer_endpoint The remote endpoint to which the socket will be - * connected. Copies will be made of the endpoint object as required. - * - * @param handler The handler to be called when the connection operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void connect_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Connect succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * boost::asio::ip::tcp::endpoint endpoint( - * boost::asio::ip::address::from_string("1.2.3.4"), 12345); - * socket.async_connect(endpoint, connect_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, - void (boost::system::error_code)) - async_connect(const endpoint_type& peer_endpoint, - BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) - { - boost::system::error_code open_ec; - if (!is_open()) - { - const protocol_type protocol = peer_endpoint.protocol(); - impl_.get_service().open(impl_.get_implementation(), protocol, open_ec); - } - - return async_initiate( - initiate_async_connect(), handler, this, peer_endpoint, open_ec); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * socket.set_option(option); - * @endcode - */ - template - void set_option(const SettableSocketOption& option) - { - boost::system::error_code ec; - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "set_option"); - } - - /// Set an option on the socket. - /** - * This function is used to set an option on the socket. - * - * @param option The new option value to be set on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa SettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Setting the IPPROTO_TCP/TCP_NODELAY option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::no_delay option(true); - * boost::system::error_code ec; - * socket.set_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID set_option(const SettableSocketOption& option, - boost::system::error_code& ec) - { - impl_.get_service().set_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * socket.get_option(option); - * bool is_set = option.value(); - * @endcode - */ - template - void get_option(GettableSocketOption& option) const - { - boost::system::error_code ec; - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - boost::asio::detail::throw_error(ec, "get_option"); - } - - /// Get an option from the socket. - /** - * This function is used to get the current value of an option on the socket. - * - * @param option The option value to be obtained from the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa GettableSocketOption @n - * boost::asio::socket_base::broadcast @n - * boost::asio::socket_base::do_not_route @n - * boost::asio::socket_base::keep_alive @n - * boost::asio::socket_base::linger @n - * boost::asio::socket_base::receive_buffer_size @n - * boost::asio::socket_base::receive_low_watermark @n - * boost::asio::socket_base::reuse_address @n - * boost::asio::socket_base::send_buffer_size @n - * boost::asio::socket_base::send_low_watermark @n - * boost::asio::ip::multicast::join_group @n - * boost::asio::ip::multicast::leave_group @n - * boost::asio::ip::multicast::enable_loopback @n - * boost::asio::ip::multicast::outbound_interface @n - * boost::asio::ip::multicast::hops @n - * boost::asio::ip::tcp::no_delay - * - * @par Example - * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::keep_alive option; - * boost::system::error_code ec; - * socket.get_option(option, ec); - * if (ec) - * { - * // An error occurred. - * } - * bool is_set = option.value(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID get_option(GettableSocketOption& option, - boost::system::error_code& ec) const - { - impl_.get_service().get_option(impl_.get_implementation(), option, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * socket.io_control(command); - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - void io_control(IoControlCommand& command) - { - boost::system::error_code ec; - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - boost::asio::detail::throw_error(ec, "io_control"); - } - - /// Perform an IO control command on the socket. - /** - * This function is used to execute an IO control command on the socket. - * - * @param command The IO control command to be performed on the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @sa IoControlCommand @n - * boost::asio::socket_base::bytes_readable @n - * boost::asio::socket_base::non_blocking_io - * - * @par Example - * Getting the number of bytes ready to read: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::socket::bytes_readable command; - * boost::system::error_code ec; - * socket.io_control(command, ec); - * if (ec) - * { - * // An error occurred. - * } - * std::size_t bytes_readable = command.get(); - * @endcode - */ - template - BOOST_ASIO_SYNC_OP_VOID io_control(IoControlCommand& command, - boost::system::error_code& ec) - { - impl_.get_service().io_control(impl_.get_implementation(), command, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the socket. - /** - * @returns @c true if the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - bool non_blocking() const - { - return impl_.get_service().non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - void non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "non_blocking"); - } - - /// Sets the non-blocking mode of the socket. - /** - * @param mode If @c true, the socket's synchronous operations will fail with - * boost::asio::error::would_block if they are unable to perform the requested - * operation immediately. If @c false, synchronous operations will block - * until complete. - * - * @param ec Set to indicate what error occurred, if any. - * - * @note The non-blocking mode has no effect on the behaviour of asynchronous - * operations. Asynchronous operations will never fail with the error - * boost::asio::error::would_block. - */ - BOOST_ASIO_SYNC_OP_VOID non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().non_blocking(impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Gets the non-blocking mode of the native socket implementation. - /** - * This function is used to retrieve the non-blocking mode of the underlying - * native socket. This mode has no effect on the behaviour of the socket - * object's synchronous operations. - * - * @returns @c true if the underlying socket is in non-blocking mode and - * direct system calls may fail with boost::asio::error::would_block (or the - * equivalent system error). - * - * @note The current non-blocking mode is cached by the socket object. - * Consequently, the return value may be incorrect if the non-blocking mode - * was set directly on the native socket. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - bool native_non_blocking() const - { - return impl_.get_service().native_non_blocking(impl_.get_implementation()); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @throws boost::system::system_error Thrown on failure. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - void native_non_blocking(bool mode) - { - boost::system::error_code ec; - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - boost::asio::detail::throw_error(ec, "native_non_blocking"); - } - - /// Sets the non-blocking mode of the native socket implementation. - /** - * This function is used to modify the non-blocking mode of the underlying - * native socket. It has no effect on the behaviour of the socket object's - * synchronous operations. - * - * @param mode If @c true, the underlying socket is put into non-blocking - * mode and direct system calls may fail with boost::asio::error::would_block - * (or the equivalent system error). - * - * @param ec Set to indicate what error occurred, if any. If the @c mode is - * @c false, but the current value of @c non_blocking() is @c true, this - * function fails with boost::asio::error::invalid_argument, as the - * combination does not make sense. - * - * @par Example - * This function is intended to allow the encapsulation of arbitrary - * non-blocking system calls as asynchronous operations, in a way that is - * transparent to the user of the socket object. The following example - * illustrates how Linux's @c sendfile system call might be encapsulated: - * @code template - * struct sendfile_op - * { - * tcp::socket& sock_; - * int fd_; - * Handler handler_; - * off_t offset_; - * std::size_t total_bytes_transferred_; - * - * // Function call operator meeting WriteHandler requirements. - * // Used as the handler for the async_write_some operation. - * void operator()(boost::system::error_code ec, std::size_t) - * { - * // Put the underlying socket into non-blocking mode. - * if (!ec) - * if (!sock_.native_non_blocking()) - * sock_.native_non_blocking(true, ec); - * - * if (!ec) - * { - * for (;;) - * { - * // Try the system call. - * errno = 0; - * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); - * ec = boost::system::error_code(n < 0 ? errno : 0, - * boost::asio::error::get_system_category()); - * total_bytes_transferred_ += ec ? 0 : n; - * - * // Retry operation immediately if interrupted by signal. - * if (ec == boost::asio::error::interrupted) - * continue; - * - * // Check if we need to run the operation again. - * if (ec == boost::asio::error::would_block - * || ec == boost::asio::error::try_again) - * { - * // We have to wait for the socket to become ready again. - * sock_.async_wait(tcp::socket::wait_write, *this); - * return; - * } - * - * if (ec || n == 0) - * { - * // An error occurred, or we have reached the end of the file. - * // Either way we must exit the loop so we can call the handler. - * break; - * } - * - * // Loop around to try calling sendfile again. - * } - * } - * - * // Pass result back to user's handler. - * handler_(ec, total_bytes_transferred_); - * } - * }; - * - * template - * void async_sendfile(tcp::socket& sock, int fd, Handler h) - * { - * sendfile_op op = { sock, fd, h, 0, 0 }; - * sock.async_wait(tcp::socket::wait_write, op); - * } @endcode - */ - BOOST_ASIO_SYNC_OP_VOID native_non_blocking( - bool mode, boost::system::error_code& ec) - { - impl_.get_service().native_non_blocking( - impl_.get_implementation(), mode, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @returns An object that represents the local endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); - * @endcode - */ - endpoint_type local_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().local_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "local_endpoint"); - return ep; - } - - /// Get the local endpoint of the socket. - /** - * This function is used to obtain the locally bound endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the local endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type local_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().local_endpoint(impl_.get_implementation(), ec); - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @returns An object that represents the remote endpoint of the socket. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); - * @endcode - */ - endpoint_type remote_endpoint() const - { - boost::system::error_code ec; - endpoint_type ep = impl_.get_service().remote_endpoint( - impl_.get_implementation(), ec); - boost::asio::detail::throw_error(ec, "remote_endpoint"); - return ep; - } - - /// Get the remote endpoint of the socket. - /** - * This function is used to obtain the remote endpoint of the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns An object that represents the remote endpoint of the socket. - * Returns a default-constructed endpoint object if an error occurred. - * - * @par Example - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - endpoint_type remote_endpoint(boost::system::error_code& ec) const - { - return impl_.get_service().remote_endpoint(impl_.get_implementation(), ec); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @throws boost::system::system_error Thrown on failure. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); - * @endcode - */ - void shutdown(shutdown_type what) - { - boost::system::error_code ec; - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - boost::asio::detail::throw_error(ec, "shutdown"); - } - - /// Disable sends or receives on the socket. - /** - * This function is used to disable send operations, receive operations, or - * both. - * - * @param what Determines what types of operation will no longer be allowed. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Shutting down the send side of the socket: - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); - * if (ec) - * { - * // An error occurred. - * } - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID shutdown(shutdown_type what, - boost::system::error_code& ec) - { - impl_.get_service().shutdown(impl_.get_implementation(), what, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.wait(boost::asio::ip::tcp::socket::wait_read); - * @endcode - */ - void wait(wait_type w) - { - boost::system::error_code ec; - impl_.get_service().wait(impl_.get_implementation(), w, ec); - boost::asio::detail::throw_error(ec, "wait"); - } - - /// Wait for the socket to become ready to read, ready to write, or to have - /// pending error conditions. - /** - * This function is used to perform a blocking wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param ec Set to indicate what error occurred, if any. - * - * @par Example - * Waiting for a socket to become readable. - * @code - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * boost::system::error_code ec; - * socket.wait(boost::asio::ip::tcp::socket::wait_read, ec); - * @endcode - */ - BOOST_ASIO_SYNC_OP_VOID wait(wait_type w, boost::system::error_code& ec) - { - impl_.get_service().wait(impl_.get_implementation(), w, ec); - BOOST_ASIO_SYNC_OP_VOID_RETURN(ec); - } - - /// Asynchronously wait for the socket to become ready to read, ready to - /// write, or to have pending error conditions. - /** - * This function is used to perform an asynchronous wait for a socket to enter - * a ready to read, write or error condition state. - * - * @param w Specifies the desired socket state. - * - * @param handler The handler to be called when the wait operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error // Result of operation - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @par Example - * @code - * void wait_handler(const boost::system::error_code& error) - * { - * if (!error) - * { - * // Wait succeeded. - * } - * } - * - * ... - * - * boost::asio::ip::tcp::socket socket(my_context); - * ... - * socket.async_wait(boost::asio::ip::tcp::socket::wait_read, wait_handler); - * @endcode - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, - void (boost::system::error_code)) - async_wait(wait_type w, BOOST_ASIO_MOVE_ARG(WaitHandler) handler) - { - return async_initiate( - initiate_async_wait(), handler, this, w); - } - -protected: - /// Protected destructor to prevent deletion through this type. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_socket_ext_local() - { - } - -#if defined(BOOST_ASIO_WINDOWS_RUNTIME) - detail::io_object_impl< - detail::null_socket_service, Executor> impl_; -#elif defined(BOOST_ASIO_HAS_IOCP) - detail::io_object_impl< - detail::win_iocp_socket_service, Executor> impl_; -#else - detail::io_object_impl< - detail::reactive_socket_service_ext_local, Executor> impl_; -#endif - -private: - // Disallow copying and assignment. - basic_socket_ext_local(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - basic_socket_ext_local& operator=(const basic_socket_ext_local&) BOOST_ASIO_DELETED; - - struct initiate_async_connect - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ConnectHandler) handler, - basic_socket_ext_local* self, const endpoint_type& peer_endpoint, - const boost::system::error_code& open_ec) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ConnectHandler. - BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; - - if (open_ec) - { - boost::asio::post(self->impl_.get_executor(), - boost::asio::detail::bind_handler( - BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler), open_ec)); - } - else - { - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_connect( - self->impl_.get_implementation(), peer_endpoint, - handler2.value, self->impl_.get_implementation_executor()); - } - } - }; - - struct initiate_async_wait - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, - basic_socket_ext_local* self, wait_type w) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_wait( - self->impl_.get_implementation(), w, handler2.value, - self->impl_.get_implementation_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_SOCKET_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/basic_stream_socket_ext.hpp b/implementation/helper/1.76/boost/asio/basic_stream_socket_ext.hpp deleted file mode 100644 index e77f5eb..0000000 --- a/implementation/helper/1.76/boost/asio/basic_stream_socket_ext.hpp +++ /dev/null @@ -1,996 +0,0 @@ -// -// basic_stream_socket_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { - -#if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL) -#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL - -// Forward declaration with defaulted arguments. -template -class basic_stream_socket_ext; - -#endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_FWD_DECL) - -/// Provides stream-oriented socket functionality. -/** - * The basic_stream_socket_ext class template provides asynchronous and blocking - * stream-oriented socket functionality. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Unsafe. - * - * @par Concepts: - * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. - */ -template -class basic_stream_socket_ext - : public basic_socket_ext_local -{ -public: - /// The type of the executor associated with the object. - typedef Executor executor_type; - - /// Rebinds the socket type to another executor. - template - struct rebind_executor - { - /// The socket type when rebound to the specified executor. - typedef basic_stream_socket_ext other; - }; - - /// The native representation of a socket. -#if defined(GENERATING_DOCUMENTATION) - typedef implementation_defined native_handle_type; -#else - typedef typename basic_socket::native_handle_type native_handle_type; -#endif - - /// The protocol type. - typedef Protocol protocol_type; - - /// The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - /// Construct a basic_stream_socket without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - */ - explicit basic_stream_socket_ext(const executor_type& ex) - : basic_socket_ext_local(ex) - { - } - - /// Construct a basic_stream_socket without opening it. - /** - * This constructor creates a stream socket without opening it. The socket - * needs to be opened and then connected or accepted before data can be sent - * or received on it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - */ - template - explicit basic_stream_socket_ext(ExecutionContext& context, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context) - { - } - - /// Construct and open a basic_stream_socket. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, const protocol_type& protocol) - : basic_socket_ext_local(ex, protocol) - { - } - - /// Construct and open a basic_stream_socket. - /** - * This constructor creates and opens a stream socket. The socket needs to be - * connected or accepted before data can be sent or received on it. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, const protocol_type& protocol, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, protocol) - { - } - - /// Construct a basic_stream_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, const endpoint_type& endpoint) - : basic_socket_ext_local(ex, endpoint) - { - } - - /// Construct a basic_stream_socket, opening it and binding it to the given - /// local endpoint. - /** - * This constructor creates a stream socket and automatically opens it bound - * to the specified endpoint on the local machine. The protocol used is the - * protocol associated with the given endpoint. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param endpoint An endpoint on the local machine to which the stream - * socket will be bound. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, const endpoint_type& endpoint, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, endpoint) - { - } - - /// Construct a basic_stream_socket on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param ex The I/O executor that the socket will use, by default, to - * dispatch handlers for any asynchronous operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - basic_stream_socket_ext(const executor_type& ex, - const protocol_type& protocol, const native_handle_type& native_socket) - : basic_socket_ext_local(ex, protocol, native_socket) - { - } - - /// Construct a basic_stream_socket on an existing native socket. - /** - * This constructor creates a stream socket object to hold an existing native - * socket. - * - * @param context An execution context which provides the I/O executor that - * the socket will use, by default, to dispatch handlers for any asynchronous - * operations performed on the socket. - * - * @param protocol An object specifying protocol parameters to be used. - * - * @param native_socket The new underlying socket implementation. - * - * @throws boost::system::system_error Thrown on failure. - */ - template - basic_stream_socket_ext(ExecutionContext& context, - const protocol_type& protocol, const native_handle_type& native_socket, - typename enable_if< - is_convertible::value - >::type* = 0) - : basic_socket_ext_local(context, protocol, native_socket) - { - } - -#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move-construct a basic_stream_socket from another. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - basic_stream_socket_ext(basic_stream_socket_ext&& other) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket from another. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - basic_stream_socket_ext& operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } - - /// Move-construct a basic_stream_socket from a socket of another protocol - /// type. - /** - * This constructor moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - template - basic_stream_socket_ext(basic_stream_socket_ext&& other, - typename enable_if< - is_convertible::value - && is_convertible::value - >::type* = 0) - : basic_socket_ext_local(std::move(other)) - { - } - - /// Move-assign a basic_stream_socket from a socket of another protocol type. - /** - * This assignment operator moves a stream socket from one object to another. - * - * @param other The other basic_stream_socket object from which the move - * will occur. - * - * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_stream_socket(const executor_type&) - * constructor. - */ - template - typename enable_if< - is_convertible::value - && is_convertible::value, - basic_stream_socket_ext& - >::type operator=(basic_stream_socket_ext&& other) - { - basic_socket_ext_local::operator=(std::move(other)); - return *this; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Destroys the socket. - /** - * This function destroys the socket, cancelling any outstanding asynchronous - * operations associated with the socket as if by calling @c cancel. - */ - ~basic_stream_socket_ext() - { - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @returns The number of bytes sent. - * - * @throws boost::system::system_error Thrown on failure. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.send(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "send"); - return s; - } - - /// Send some data on the socket. - /** - * This function is used to send data on the stream socket. The function - * call will block until one or more bytes of the data has been sent - * successfully, or an until error occurs. - * - * @param buffers One or more data buffers to be sent on the socket. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes sent. Returns 0 if an error occurred. - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref write function if you need to ensure that all data - * is written before the blocking operation completes. - */ - template - std::size_t send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous send. - /** - * This function is used to asynchronously send data on the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be sent on the socket. Although - * the buffers object may be copied as necessary, ownership of the underlying - * memory blocks is retained by the caller, which must guarantee that they - * remain valid until the handler is called. - * - * @param flags Flags specifying how the send call is to be made. - * - * @param handler The handler to be called when the send operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes sent. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The send operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To send a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_send(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on sending multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t)) - async_send(const ConstBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, buffers, flags); - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on the socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @returns The number of bytes received. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.receive(boost::asio::buffer(data, size), 0); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - boost::asio::detail::throw_error(ec, "receive"); - return s; - } - - /// Receive some data on a connected socket. - /** - * This function is used to receive data on the stream socket. The function - * call will block until one or more bytes of data has been received - * successfully, or until an error occurs. - * - * @param buffers One or more buffers into which the data will be received. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes received. Returns 0 if an error occurred. - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that the - * requested amount of data is read before the blocking operation completes. - */ - template - std::size_t receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, flags, ec); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Start an asynchronous receive. - /** - * This function is used to asynchronously receive data from the stream - * socket. The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be received. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param flags Flags specifying how the receive call is to be made. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The function - * signature of the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes received. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The receive operation may not receive all of the requested number of - * bytes. Consider using the @ref async_read function if you need to ensure - * that the requested amount of data is received before the asynchronous - * operation completes. - * - * @par Example - * To receive into a single data buffer use the @ref buffer function as - * follows: - * @code - * socket.async_receive(boost::asio::buffer(data, size), 0, handler); - * @endcode - * See the @ref buffer documentation for information on receiving into - * multiple buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_receive(const MutableBufferSequence& buffers, - socket_base::message_flags flags, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, buffers, flags); - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @returns The number of bytes written. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.write_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "write_some"); - return s; - } - - /// Write some data to the socket. - /** - * This function is used to write data to the stream socket. The function call - * will block until one or more bytes of the data has been written - * successfully, or until an error occurs. - * - * @param buffers One or more data buffers to be written to the socket. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes written. Returns 0 if an error occurred. - * - * @note The write_some operation may not transmit all of the data to the - * peer. Consider using the @ref write function if you need to ensure that - * all data is written before the blocking operation completes. - */ - template - std::size_t write_some(const ConstBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->impl_.get_service().send( - this->impl_.get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous write. - /** - * This function is used to asynchronously write data to the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more data buffers to be written to the socket. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the write operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes written. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The write operation may not transmit all of the data to the peer. - * Consider using the @ref async_write function if you need to ensure that all - * data is written before the asynchronous operation completes. - * - * @par Example - * To write a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_write_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on writing multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_write_some(const ConstBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(WriteHandler) handler) - { - return async_initiate( - initiate_async_send(), handler, this, - buffers, socket_base::message_flags(0)); - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @returns The number of bytes read. - * - * @throws boost::system::system_error Thrown on failure. An error code of - * boost::asio::error::eof indicates that the connection was closed by the - * peer. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.read_some(boost::asio::buffer(data, size)); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers) - { - boost::system::error_code ec; - std::size_t s = this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - boost::asio::detail::throw_error(ec, "read_some"); - return s; - } - - /// Read some data from the socket. - /** - * This function is used to read data from the stream socket. The function - * call will block until one or more bytes of data has been read successfully, - * or until an error occurs. - * - * @param buffers One or more buffers into which the data will be read. - * - * @param ec Set to indicate what error occurred, if any. - * - * @returns The number of bytes read. Returns 0 if an error occurred. - * - * @note The read_some operation may not read all of the requested number of - * bytes. Consider using the @ref read function if you need to ensure that - * the requested amount of data is read before the blocking operation - * completes. - */ - template - std::size_t read_some(const MutableBufferSequence& buffers, - boost::system::error_code& ec) - { - return this->impl_.get_service().receive( - this->impl_.get_implementation(), buffers, 0, ec); - } - - /// Start an asynchronous read. - /** - * This function is used to asynchronously read data from the stream socket. - * The function call always returns immediately. - * - * @param buffers One or more buffers into which the data will be read. - * Although the buffers object may be copied as necessary, ownership of the - * underlying memory blocks is retained by the caller, which must guarantee - * that they remain valid until the handler is called. - * - * @param handler The handler to be called when the read operation completes. - * Copies will be made of the handler as required. The function signature of - * the handler must be: - * @code void handler( - * const boost::system::error_code& error, // Result of operation. - * std::size_t bytes_transferred // Number of bytes read. - * ); @endcode - * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. On - * immediate completion, invocation of the handler will be performed in a - * manner equivalent to using boost::asio::post(). - * - * @note The read operation may not read all of the requested number of bytes. - * Consider using the @ref async_read function if you need to ensure that the - * requested amount of data is read before the asynchronous operation - * completes. - * - * @par Example - * To read into a single data buffer use the @ref buffer function as follows: - * @code - * socket.async_read_some(boost::asio::buffer(data, size), handler); - * @endcode - * See the @ref buffer documentation for information on reading into multiple - * buffers in one go, and how to use it with arrays, boost::array or - * std::vector. - */ - template - BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, - void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) - async_read_some(const MutableBufferSequence& buffers, - BOOST_ASIO_MOVE_ARG(ReadHandler) handler) - { - return async_initiate( - initiate_async_receive(), handler, this, - buffers, socket_base::message_flags(0)); - } - -private: - struct initiate_async_send - { - template - void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, - basic_stream_socket_ext* self, const ConstBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a WriteHandler. - BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_send( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; - - struct initiate_async_receive - { - template - void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, - basic_stream_socket_ext* self, const MutableBufferSequence& buffers, - socket_base::message_flags flags) const - { - // If you get an error on the following line it means that your handler - // does not meet the documented type requirements for a ReadHandler. - BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; - - detail::non_const_lvalue handler2(handler); - self->impl_.get_service().async_receive( - self->impl_.get_implementation(), buffers, flags, - handler2.value, self->impl_.get_executor()); - } - }; -}; - -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext.hpp deleted file mode 100644 index 67fe6bd..0000000 --- a/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext.hpp +++ /dev/null @@ -1,586 +0,0 @@ -// -// detail/handler_type_requirements_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3)), - char(0)); - -template -char (&three_arg_handler_test(Handler, ...))[2]; - -template -auto three_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3 *a3) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3))), - char(0)); - -template -char (&three_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - boost::asio::ip::address)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::three_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext_local.hpp deleted file mode 100644 index 65640ad..0000000 --- a/implementation/helper/1.76/boost/asio/detail/handler_type_requirements_ext_local.hpp +++ /dev/null @@ -1,588 +0,0 @@ -// -// detail/handler_type_requirements_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -// Older versions of gcc have difficulty compiling the sizeof expressions where -// we test the handler type requirements. We'll disable checking of handler type -// requirements for those compilers, but otherwise enable it by default. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) -# if !defined(__GNUC__) || (__GNUC__ >= 4) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 -# endif // !defined(__GNUC__) || (__GNUC__ >= 4) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -// With C++0x we can use a combination of enhanced SFINAE and static_assert to -// generate better template error messages. As this technique is not yet widely -// portable, we'll only enable it for tested compilers. -#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) -# if defined(__GNUC__) -# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# if defined(__GXX_EXPERIMENTAL_CXX0X__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) -# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) -# endif // defined(__GNUC__) -# if defined(BOOST_ASIO_MSVC) -# if (_MSC_VER >= 1600) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // (_MSC_VER >= 1600) -# endif // defined(BOOST_ASIO_MSVC) -# if defined(__clang__) -# if __has_feature(__cxx_static_assert__) -# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 -# endif // __has_feature(cxx_static_assert) -# endif // defined(__clang__) -#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) -# include -#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -namespace boost { -namespace asio { -namespace detail { - -#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template -auto zero_arg_copyable_handler_test(Handler h, void*) - -> decltype( - sizeof(Handler(static_cast(h))), - ((h)()), - char(0)); - -template -char (&zero_arg_copyable_handler_test(Handler, ...))[2]; - -template -auto one_arg_handler_test(Handler h, Arg1* a1) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1)), - char(0)); - -template -char (&one_arg_handler_test(Handler h, ...))[2]; - -template -auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2)), - char(0)); - -template -char (&two_arg_handler_test(Handler, ...))[2]; - -template -auto two_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2))), - char(0)); - -template -char (&two_arg_move_handler_test(Handler, ...))[2]; - -template -auto four_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, *a2, *a3, *a4)), - char(0)); - -template -char (&four_arg_handler_test(Handler, ...))[2]; - -template -auto four_arg_move_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) - -> decltype( - sizeof(Handler(BOOST_ASIO_MOVE_CAST(Handler)(h))), - ((h)(*a1, BOOST_ASIO_MOVE_CAST(Arg2)(*a2), BOOST_ASIO_MOVE_CAST(Arg3)(*a3), BOOST_ASIO_MOVE_CAST(Arg4)(*a4))), - char(0)); - -template -char (&four_arg_move_handler_test(Handler, ...))[2]; - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ - static_assert(expr, msg); - -# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) - -# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) - -template T& lvref(); -template T& lvref(T); -template const T& clvref(); -template const T& clvref(T); -#if defined(BOOST_ASIO_HAS_MOVE) -template T rvref(); -template T rvref(T); -#else // defined(BOOST_ASIO_HAS_MOVE) -template const T& rvref(); -template const T& rvref(T); -#endif // defined(BOOST_ASIO_HAS_MOVE) -template char argbyv(T); - -#if 0 -template -struct handler_type_requirements -{ -}; -#endif - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void()) asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::zero_arg_copyable_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), 0)) == 1, \ - "CompletionHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()(), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t, \ - std::uint32_t, std::uint32_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::four_arg_handler_test( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ReadHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::clvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "WriteHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#if 0 -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "AcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, socket_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_move_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "MoveAcceptHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::rvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF -#endif - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, endpoint_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, endpoint_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "RangeConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, iter_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "IteratorConnectHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, range_type) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, range_type)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "ResolveHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "WaitHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, int)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "SignalHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "HandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code, std::size_t)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::two_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0), \ - static_cast(0))) == 1, \ - "BufferedHandshakeHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref(), \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - \ - typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ - void(boost::system::error_code)) \ - asio_true_handler_type; \ - \ - BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ - sizeof(boost::asio::detail::one_arg_handler_test( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>(), \ - static_cast(0))) == 1, \ - "ShutdownHandler type requirements not met") \ - \ - typedef boost::asio::detail::handler_type_requirements< \ - sizeof( \ - boost::asio::detail::argbyv( \ - boost::asio::detail::rvref< \ - asio_true_handler_type>())) + \ - sizeof( \ - boost::asio::detail::lvref< \ - asio_true_handler_type>()( \ - boost::asio::detail::lvref()), \ - char(0))> BOOST_ASIO_UNUSED_TYPEDEF - -#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -#define BOOST_ASIO_LEGACY_COMPLETION_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_READ_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_MOVE_ACCEPT_HANDLER_CHECK( \ - handler_type, handler, socket_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RANGE_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_ITERATOR_CONNECT_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ - handler_type, handler, iter_type) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ - handler_type, handler) \ - typedef int BOOST_ASIO_UNUSED_TYPEDEF - -#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp deleted file mode 100644 index 04036ad..0000000 --- a/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext::reactive_socket_service_base_ext( - execution_context& context) - : reactor_(use_service(context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext::base_shutdown() -{ -} - -void reactive_socket_service_base_ext::construct( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext::base_move_construct( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::base_move_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - reactive_socket_service_base_ext::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext::destroy( - reactive_socket_service_base_ext::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext::close( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext::cancel( - reactive_socket_service_base_ext::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_open( - reactive_socket_service_base_ext::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext::do_assign( - reactive_socket_service_base_ext::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext::start_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext::start_accept_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext::start_connect_op( - reactive_socket_service_base_ext::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP diff --git a/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp b/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp deleted file mode 100644 index 288cf19..0000000 --- a/implementation/helper/1.76/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp +++ /dev/null @@ -1,302 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local( - execution_context& context) - : reactor_(use_service(context)) -{ - reactor_.init_task(); -} - -void reactive_socket_service_base_ext_local::base_shutdown() -{ -} - -void reactive_socket_service_base_ext_local::construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - impl.socket_ = invalid_socket; - impl.state_ = 0; -} - -void reactive_socket_service_base_ext_local::base_move_construct( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::base_move_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - reactive_socket_service_base_ext_local::base_implementation_type& other_impl) -{ - destroy(impl); - - impl.socket_ = other_impl.socket_; - other_impl.socket_ = invalid_socket; - - impl.state_ = other_impl.state_; - other_impl.state_ = 0; - - other_service.reactor_.move_descriptor(impl.socket_, - impl.reactor_data_, other_impl.reactor_data_); -} - -void reactive_socket_service_base_ext_local::destroy( - reactive_socket_service_base_ext_local::base_implementation_type& impl) -{ - if (impl.socket_ != invalid_socket) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - boost::system::error_code ignored_ec; - socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } -} - -boost::system::error_code reactive_socket_service_base_ext_local::close( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "close")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, - (impl.state_ & socket_ops::possible_dup) == 0); - - socket_ops::close(impl.socket_, impl.state_, false, ec); - - reactor_.cleanup_descriptor_data(impl.reactor_data_); - } - else - { - ec = boost::system::error_code(); - } - - // The descriptor is closed by the OS even if close() returns an error. - // - // (Actually, POSIX says the state of the descriptor is unspecified. On - // Linux the descriptor is apparently closed anyway; e.g. see - // http://lkml.org/lkml/2005/9/10/129 - // We'll just have to assume that other OSes follow the same behaviour. The - // known exception is when Windows's closesocket() function fails with - // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). - construct(impl); - - return ec; -} -/* -socket_type reactive_socket_service_base::release( - reactive_socket_service_base::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return invalid_socket; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "release")); - - reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, false); - reactor_.cleanup_descriptor_data(impl.reactor_data_); - socket_type sock = impl.socket_; - construct(impl); - ec = boost::system::error_code(); - return sock; -} -*/ -boost::system::error_code reactive_socket_service_base_ext_local::cancel( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - boost::system::error_code& ec) -{ - if (!is_open(impl)) - { - ec = boost::asio::error::bad_descriptor; - return ec; - } - - BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), - "socket", &impl, impl.socket_, "cancel")); - - reactor_.cancel_ops(impl.socket_, impl.reactor_data_); - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_open( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int af, int type, int protocol, boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - socket_holder sock(socket_ops::socket(af, type, protocol, ec)); - if (sock.get() == invalid_socket) - return ec; - - if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = sock.release(); - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - ec = boost::system::error_code(); - return ec; -} - -boost::system::error_code reactive_socket_service_base_ext_local::do_assign( - reactive_socket_service_base_ext_local::base_implementation_type& impl, int type, - const reactive_socket_service_base_ext_local::native_handle_type& native_socket, - boost::system::error_code& ec) -{ - if (is_open(impl)) - { - ec = boost::asio::error::already_open; - return ec; - } - - if (int err = reactor_.register_descriptor( - native_socket, impl.reactor_data_)) - { - ec = boost::system::error_code(err, - boost::asio::error::get_system_category()); - return ec; - } - - impl.socket_ = native_socket; - switch (type) - { - case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; - case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; - default: impl.state_ = 0; break; - } - impl.state_ |= socket_ops::possible_dup; - ec = boost::system::error_code(); - return ec; -} - -void reactive_socket_service_base_ext_local::start_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - int op_type, reactor_op* op, bool is_continuation, - bool is_non_blocking, bool noop) -{ - if (!noop) - { - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - reactor_.start_op(op_type, impl.socket_, - impl.reactor_data_, op, is_continuation, is_non_blocking); - return; - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -void reactive_socket_service_base_ext_local::start_accept_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open) -{ - if (!peer_is_open) - start_op(impl, reactor::read_op, op, is_continuation, true, false); - else - { - op->ec_ = boost::asio::error::already_open; - reactor_.post_immediate_completion(op, is_continuation); - } -} - -void reactive_socket_service_base_ext_local::start_connect_op( - reactive_socket_service_base_ext_local::base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen) -{ - if ((impl.state_ & socket_ops::non_blocking) - || socket_ops::set_internal_non_blocking( - impl.socket_, impl.state_, true, op->ec_)) - { - if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) - { - if (op->ec_ == boost::asio::error::in_progress - || op->ec_ == boost::asio::error::would_block) - { - op->ec_ = boost::system::error_code(); - reactor_.start_op(reactor::connect_op, impl.socket_, - impl.reactor_data_, op, is_continuation, false); - return; - } - } - } - - reactor_.post_immediate_completion(op, is_continuation); -} - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP diff --git a/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext.ipp deleted file mode 100644 index 39e2ed8..0000000 --- a/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext.ipp +++ /dev/null @@ -1,234 +0,0 @@ -// -// detail/impl/socket_ops_ext.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; - LPFN_WSARECVMSG WSARecvMsg; - DWORD NumberOfBytes; - signed_size_type result; - - result = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, - &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, - &WSARecvMsg, sizeof WSARecvMsg, - &NumberOfBytes, NULL, NULL); - get_last_error(ec, true); - if (ec.value() == SOCKET_ERROR) { - WSARecvMsg = NULL; - return 0; - } - - WSABUF wsaBuf; - WSAMSG msg; - char controlBuffer[1024]; - msg.name = addr; - msg.namelen = *addrlen; - wsaBuf.buf = bufs->buf; - wsaBuf.len = bufs->len; - msg.lpBuffers = &wsaBuf; - msg.dwBufferCount = count; - msg.Control.len = sizeof controlBuffer; - msg.Control.buf = controlBuffer; - msg.dwFlags = flags; - - DWORD dwNumberOfBytesRecvd; - result = WSARecvMsg(s, &msg, &dwNumberOfBytesRecvd, NULL, NULL); - get_last_error(ec, true); - - if (result >= 0) { - ec = boost::system::error_code(); - - // Find destination address - for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = WSA_CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) WSA_CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } else { - dwNumberOfBytesRecvd = -1; - } - return dwNumberOfBytesRecvd; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - char cmbuf[0x100]; - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - msg.msg_control = cmbuf; - msg.msg_controllen = sizeof(cmbuf); - signed_size_type result = ::recvmsg(s, &msg, flags); - get_last_error(ec, true); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec.assign(0, ec.category()); - - // Find destination address - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) - { - struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); - } - } else - if (cmsg->cmsg_level == IPPROTO_IPV6 && cmsg->cmsg_type == IPV6_PKTINFO) - { - struct in6_pktinfo *pi = (struct in6_pktinfo *) CMSG_DATA(cmsg); - if (pi) - { - boost::asio::ip::address_v6::bytes_type b; - memcpy(b.data(), pi->ipi6_addr.s6_addr, sizeof(pi->ipi6_addr.s6_addr)); - da = boost::asio::ip::address_v6(b); - } - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, boost::asio::ip::address& da) -{ - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, boost::asio::ip::address& da) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, da); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP diff --git a/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext_local.ipp b/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext_local.ipp deleted file mode 100644 index 83a673b..0000000 --- a/implementation/helper/1.76/boost/asio/detail/impl/socket_ops_ext_local.ipp +++ /dev/null @@ -1,307 +0,0 @@ -// -// detail/impl/socket_ops_ext_local.ipp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP - -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -signed_size_type recv(socket_type s, buf* bufs, size_t count, - int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int result = ::WSARecv(s, bufs, - recv_buf_count, &bytes_transferred, &recv_flags, 0, 0); - get_last_error(ec, true); - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec.assign(0, ec.category()); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = ::recvmsg(s, &msg, flags); - get_last_error(ec, true); - if (result >= 0) { - ec.assign(0, ec.category()); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, - int flags, socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - struct ucred *ucredp; - clear_last_error(); -#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - // Receive some data. - DWORD recv_buf_count = static_cast(count); - DWORD bytes_transferred = 0; - DWORD recv_flags = flags; - int tmp_addrlen = (int)*addrlen; - int result = ::WSARecvFrom(s, bufs, recv_buf_count, - &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0); - get_last_error(ec, true); - *addrlen = (std::size_t)tmp_addrlen; - if (ec.value() == ERROR_NETNAME_DELETED) - ec = boost::asio::error::connection_reset; - else if (ec.value() == ERROR_PORT_UNREACHABLE) - ec = boost::asio::error::connection_refused; - if (result != 0) - return socket_error_retval; - ec.assign(0, ec.category()); - return bytes_transferred; -#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) - msghdr msg = msghdr(); - init_msghdr_msg_name(msg.msg_name, addr); - msg.msg_namelen = static_cast(*addrlen); - msg.msg_iov = bufs; - msg.msg_iovlen = static_cast(count); - - union { - struct cmsghdr cmh; - char control[CMSG_SPACE(sizeof(struct ucred))]; - } control_un; - - // Set 'control_un' to describe ancillary data that we want to receive - control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); - control_un.cmh.cmsg_level = SOL_SOCKET; - control_un.cmh.cmsg_type = SCM_CREDENTIALS; - - // Set 'msg' fields to describe 'control_un' - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - signed_size_type result = ::recvmsg(s, &msg, flags); - get_last_error(ec, true); - *addrlen = msg.msg_namelen; - if (result >= 0) { - ec.assign(0, ec.category()); - - // Find UID / GID - for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); - cmsg != NULL; - cmsg = CMSG_NXTHDR(&msg, cmsg)) - { - if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS - || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) - continue; - - ucredp = (struct ucred *) CMSG_DATA(cmsg); - if (ucredp) { - uid = ucredp->uid; - gid = ucredp->gid; - } - } - } - return result; -#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) -} - -size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - if (s == invalid_socket) - { - ec = boost::asio::error::bad_descriptor; - return 0; - } - - // Read some data. - for (;;) - { - // Try to complete the operation without blocking. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Check if operation succeeded. - if (bytes >= 0) - return bytes; - - // Operation failed. - if ((state & user_set_non_blocking) - || (ec != boost::asio::error::would_block - && ec != boost::asio::error::try_again)) - return 0; - - // Wait for socket to become ready. - if (socket_ops::poll_read(s, 0, -1, ec) < 0) - return 0; - } -} - -#if defined(BOOST_ASIO_HAS_IOCP) - -void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid) -{ - uid = 0xFFFFFFFF; - gid = 0xFFFFFFFF; - // Map non-portable errors to their portable counterparts. - if (ec.value() == ERROR_NETNAME_DELETED) - { - if (cancel_token.expired()) - ec = boost::asio::error::operation_aborted; - else - ec = boost::asio::error::connection_reset; - } - else if (ec.value() == ERROR_PORT_UNREACHABLE) - { - ec = boost::asio::error::connection_refused; - } -} - -#else // defined(BOOST_ASIO_HAS_IOCP) - -bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec, uid, gid); - - // Check for end of stream. - if (is_stream && bytes == 0) - { - ec = boost::asio::error::eof; - return true; - } - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid) -{ - for (;;) - { - // Read some data. - signed_size_type bytes = socket_ops::recvfrom( - s, bufs, count, flags, addr, addrlen, ec, uid, gid); - - // Retry operation if interrupted by signal. - if (ec == boost::asio::error::interrupted) - continue; - - // Check if we need to run the operation again. - if (ec == boost::asio::error::would_block - || ec == boost::asio::error::try_again) - return false; - - // Operation is complete. - if (bytes >= 0) - { - ec = boost::system::error_code(); - bytes_transferred = bytes; - } - else - bytes_transferred = 0; - - return true; - } -} - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext.hpp deleted file mode 100644 index 1167d57..0000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext.hpp +++ /dev/null @@ -1,162 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recv_op_base_ext(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(success_ec, &reactive_socket_recv_op_base_ext::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext* o( - static_cast(base)); - - typedef buffer_sequence_adapter bufs_type; - - status result; - if (bufs_type::is_single_buffer) - { - result = socket_ops::non_blocking_recv1(o->socket_, - bufs_type::first(o->buffers_).data(), - bufs_type::first(o->buffers_).size(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - else - { - bufs_type bufs(o->buffers_); - result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext : - public reactive_socket_recv_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext); - - reactive_socket_recv_op_ext(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - : reactive_socket_recv_op_base_ext(success_ec, - socket, state, buffers, flags, - &reactive_socket_recv_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp deleted file mode 100644 index bedbd29..0000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp +++ /dev/null @@ -1,162 +0,0 @@ -// -// detail/reactive_socket_recv_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recv_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recv_op_base_ext_local(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(success_ec, &reactive_socket_recv_op_base_ext_local::do_perform, complete_func), - socket_(socket), - state_(state), - buffers_(buffers), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recv_op_base_ext_local* o( - static_cast(base)); - - typedef buffer_sequence_adapter bufs_type; - - status result; - if (bufs_type::is_single_buffer) - { - result = socket_ops::non_blocking_recv1(o->socket_, - bufs_type::first(o->buffers_).data(), - bufs_type::first(o->buffers_).size(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - else - { - bufs_type bufs(o->buffers_); - result = socket_ops::non_blocking_recv(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - (o->state_ & socket_ops::stream_oriented) != 0, - o->ec_, o->bytes_transferred_) ? done : not_done; - } - - if (result == done) - if ((o->state_ & socket_ops::stream_oriented) != 0) - if (o->bytes_transferred_ == 0) - result = done_and_exhausted; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recv", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - socket_ops::state_type state_; - MutableBufferSequence buffers_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recv_op_ext_local : - public reactive_socket_recv_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext_local); - - reactive_socket_recv_op_ext_local(const boost::system::error_code& success_ec, - socket_type socket, socket_ops::state_type state, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - : reactive_socket_recv_op_base_ext_local(success_ec, - socket, state, buffers, flags, - &reactive_socket_recv_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recv_op_ext_local* o(static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3, handler.arg4)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp deleted file mode 100644 index 875fe14..0000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp +++ /dev/null @@ -1,153 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvfrom_op_base_ext(const boost::system::error_code& success_ec, - socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext(success_ec, &reactive_socket_recvfrom_op_base_ext::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->da_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext : - public reactive_socket_recvfrom_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext); - - reactive_socket_recvfrom_op_ext(const boost::system::error_code& success_ec, - socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvfrom_op_base_ext( - success_ec, socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp deleted file mode 100644 index f9fef2b..0000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp +++ /dev/null @@ -1,148 +0,0 @@ -// -// detail/reactive_socket_recvfrom_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvfrom_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvfrom_op_base_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, func_type complete_func) - : reactor_op_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func), - socket_(socket), - protocol_type_(protocol_type), - buffers_(buffers), - sender_endpoint_(endpoint), - flags_(flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvfrom_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - std::size_t addr_len = o->sender_endpoint_.capacity(); - status result = socket_ops::non_blocking_recvfrom(o->socket_, - bufs.buffers(), bufs.count(), o->flags_, - o->sender_endpoint_.data(), &addr_len, - o->ec_, o->bytes_transferred_, o->uid_, o->gid_) ? done : not_done; - - if (result && !o->ec_) - o->sender_endpoint_.resize(addr_len); - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvfrom", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - int protocol_type_; - MutableBufferSequence buffers_; - Endpoint& sender_endpoint_; - socket_base::message_flags flags_; -}; - -template -class reactive_socket_recvfrom_op_ext_local : - public reactive_socket_recvfrom_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext_local); - - reactive_socket_recvfrom_op_ext_local(socket_type socket, int protocol_type, - const MutableBufferSequence& buffers, Endpoint& endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvfrom_op_base_ext_local( - socket, protocol_type, buffers, endpoint, flags, - &reactive_socket_recvfrom_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvfrom_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp deleted file mode 100644 index bd315dc..0000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp +++ /dev/null @@ -1,144 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext : public reactor_op_ext -{ -public: - reactive_socket_recvmsg_op_base_ext(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext(&reactive_socket_recvmsg_op_base_ext::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext : - public reactive_socket_recvmsg_op_base_ext -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext); - - reactive_socket_recvmsg_op_ext(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvmsg_op_base_ext(socket, buffers, - in_flags, out_flags, &reactive_socket_recvmsg_op_ext::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder3 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp deleted file mode 100644 index 8148690..0000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// detail/reactive_socket_recvmsg_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_recvmsg_op_base_ext_local : public reactor_op_ext_local -{ -public: - reactive_socket_recvmsg_op_base_ext_local(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, func_type complete_func) - : reactor_op_ext_local(success_ec, &reactive_socket_recvmsg_op_base_ext_local::do_perform, complete_func), - socket_(socket), - buffers_(buffers), - in_flags_(in_flags), - out_flags_(out_flags) - { - } - - static status do_perform(reactor_op* base) - { - reactive_socket_recvmsg_op_base_ext_local* o( - static_cast(base)); - - buffer_sequence_adapter bufs(o->buffers_); - - status result = socket_ops::non_blocking_recvmsg(o->socket_, - bufs.buffers(), bufs.count(), - o->in_flags_, o->out_flags_, - o->ec_, o->bytes_transferred_) ? done : not_done; - - BOOST_ASIO_HANDLER_REACTOR_OPERATION((*o, "non_blocking_recvmsg", - o->ec_, o->bytes_transferred_)); - - return result; - } - -private: - socket_type socket_; - MutableBufferSequence buffers_; - socket_base::message_flags in_flags_; - socket_base::message_flags& out_flags_; -}; - -template -class reactive_socket_recvmsg_op_ext_local : - public reactive_socket_recvmsg_op_base_ext_local -{ -public: - BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext_local); - - reactive_socket_recvmsg_op_ext_local(const boost::system::error_code& success_ec, - socket_type socket, const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - : reactive_socket_recvmsg_op_base_ext_local(success_ec, - socket, buffers, in_flags, out_flags, - &reactive_socket_recvmsg_op_ext_local::do_complete), - handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)), - work_(handler_, io_ex) - { - } - - static void do_complete(void* owner, operation* base, - const boost::system::error_code& /*ec*/, - std::size_t /*bytes_transferred*/) - { - // Take ownership of the handler object. - reactive_socket_recvmsg_op_ext_local* o( - static_cast(base)); - ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; - - BOOST_ASIO_HANDLER_COMPLETION((*o)); - - // Take ownership of the operation's outstanding work. - handler_work w( - BOOST_ASIO_MOVE_CAST2(handler_work)( - o->work_)); - - // Make a copy of the handler so that the memory can be deallocated before - // the upcall is made. Even if we're not about to make an upcall, a - // sub-object of the handler may be the true owner of the memory associated - // with the handler. Consequently, a local copy of the handler is required - // to ensure that any owning sub-object remains valid until after we have - // deallocated the memory here. - detail::binder4 - handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); - p.h = boost::asio::detail::addressof(handler.handler_); - p.reset(); - - // Make the upcall if required. - if (owner) - { - fenced_block b(fenced_block::half); - BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); - w.complete(handler, handler.handler_); - BOOST_ASIO_HANDLER_INVOCATION_END; - } - } - -private: - Handler handler_; - handler_work work_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext.hpp deleted file mode 100644 index 2e68a87..0000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext.hpp +++ /dev/null @@ -1,524 +0,0 @@ -// -// detail/reactive_socket_service_base.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext(execution_context& context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op< - ConstBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - in_flags, out_flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; - - // Cached success value to avoid accessing category singleton. - const boost::system::error_code success_ec_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext_local.hpp deleted file mode 100644 index a71fce5..0000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_base_ext_local.hpp +++ /dev/null @@ -1,524 +0,0 @@ -// -// detail/reactive_socket_service_base_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) \ - && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactive_socket_service_base_ext_local -{ -public: - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct base_implementation_type - { - // The native socket representation. - socket_type socket_; - - // The current state of the socket. - socket_ops::state_type state_; - - // Per-descriptor data used by the reactor. - reactor::per_descriptor_data reactor_data_; - }; - - // Constructor. - BOOST_ASIO_DECL reactive_socket_service_base_ext_local(execution_context& context); - - // Destroy all user-defined handler objects owned by the service. - BOOST_ASIO_DECL void base_shutdown(); - - // Construct a new socket implementation. - BOOST_ASIO_DECL void construct(base_implementation_type& impl); - - // Move-construct a new socket implementation. - BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, - base_implementation_type& other_impl); - - // Move-assign from another socket implementation. - BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - base_implementation_type& other_impl); - - // Destroy a socket implementation. - BOOST_ASIO_DECL void destroy(base_implementation_type& impl); - - // Determine whether the socket is open. - bool is_open(const base_implementation_type& impl) const - { - return impl.socket_ != invalid_socket; - } - - // Destroy a socket implementation. - BOOST_ASIO_DECL boost::system::error_code close( - base_implementation_type& impl, boost::system::error_code& ec); - - // Release ownership of the socket. - BOOST_ASIO_DECL socket_type release( - base_implementation_type& impl, boost::system::error_code& ec); - - // Get the native socket representation. - native_handle_type native_handle(base_implementation_type& impl) - { - return impl.socket_; - } - - // Cancel all operations associated with the socket. - BOOST_ASIO_DECL boost::system::error_code cancel( - base_implementation_type& impl, boost::system::error_code& ec); - - // Determine whether the socket is at the out-of-band data mark. - bool at_mark(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::sockatmark(impl.socket_, ec); - } - - // Determine the number of bytes available for reading. - std::size_t available(const base_implementation_type& impl, - boost::system::error_code& ec) const - { - return socket_ops::available(impl.socket_, ec); - } - - // Place the socket into the state where it will listen for new connections. - boost::system::error_code listen(base_implementation_type& impl, - int backlog, boost::system::error_code& ec) - { - socket_ops::listen(impl.socket_, backlog, ec); - return ec; - } - - // Perform an IO control command on the socket. - template - boost::system::error_code io_control(base_implementation_type& impl, - IO_Control_Command& command, boost::system::error_code& ec) - { - socket_ops::ioctl(impl.socket_, impl.state_, command.name(), - static_cast(command.data()), ec); - return ec; - } - - // Gets the non-blocking mode of the socket. - bool non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::user_set_non_blocking) != 0; - } - - // Sets the non-blocking mode of the socket. - boost::system::error_code non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Gets the non-blocking mode of the native socket implementation. - bool native_non_blocking(const base_implementation_type& impl) const - { - return (impl.state_ & socket_ops::internal_non_blocking) != 0; - } - - // Sets the non-blocking mode of the native socket implementation. - boost::system::error_code native_non_blocking(base_implementation_type& impl, - bool mode, boost::system::error_code& ec) - { - socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); - return ec; - } - - // Wait for the socket to become ready to read, ready to write, or to have - // pending error conditions. - boost::system::error_code wait(base_implementation_type& impl, - socket_base::wait_type w, boost::system::error_code& ec) - { - switch (w) - { - case socket_base::wait_read: - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_write: - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - break; - case socket_base::wait_error: - socket_ops::poll_error(impl.socket_, impl.state_, -1, ec); - break; - default: - ec = boost::asio::error::invalid_argument; - break; - } - - return ec; - } - - // Asynchronously wait for the socket to become ready to read, ready to - // write, or to have pending error conditions. - template - void async_wait(base_implementation_type& impl, - socket_base::wait_type w, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_wait_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_wait")); - - int op_type; - switch (w) - { - case socket_base::wait_read: - op_type = reactor::read_op; - break; - case socket_base::wait_write: - op_type = reactor::write_op; - break; - case socket_base::wait_error: - op_type = reactor::except_op; - break; - default: - p.p->ec_ = boost::asio::error::invalid_argument; - reactor_.post_immediate_completion(p.p, is_continuation); - p.v = p.p = 0; - return; - } - - start_op(impl, op_type, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Send the given data to the peer. - template - size_t send(base_implementation_type& impl, - const ConstBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_send(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be sent without blocking. - size_t send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send(base_implementation_type& impl, - const ConstBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_send_op< - ConstBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data from the peer. Returns the number of bytes received. - template - size_t receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recv(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); - } - - // Wait until data can be received without blocking. - size_t receive(base_implementation_type& impl, const null_buffers&, - socket_base::message_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recv_op_ext_local< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, - buffers, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (flags & socket_base::message_out_of_band) == 0, - ((impl.state_ & socket_ops::stream_oriented) - && buffer_sequence_adapter::all_empty(buffers))); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive(null_buffers)")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive some data with associated flags. Returns the number of bytes - // received. - template - size_t receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, - socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_recvmsg(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), in_flags, out_flags, ec); - } - - // Wait until data can be received without blocking. - size_t receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags, - socket_base::message_flags& out_flags, boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received - // must be valid for the lifetime of the asynchronous operation. - template - void async_receive_with_flags(base_implementation_type& impl, - const MutableBufferSequence& buffers, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvmsg_op_ext_local< - MutableBufferSequence, Handler, IoExecutor> op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - in_flags, out_flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags")); - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, - (in_flags & socket_base::message_out_of_band) == 0, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_with_flags(base_implementation_type& impl, - const null_buffers&, socket_base::message_flags in_flags, - socket_base::message_flags& out_flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_with_flags(null_buffers)")); - - // Clear out_flags, since we cannot give it any other sensible value when - // performing a null_buffers operation. - out_flags = 0; - - start_op(impl, - (in_flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - -protected: - // Open a new socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_open( - base_implementation_type& impl, int af, - int type, int protocol, boost::system::error_code& ec); - - // Assign a native socket to a socket implementation. - BOOST_ASIO_DECL boost::system::error_code do_assign( - base_implementation_type& impl, int type, - const native_handle_type& native_socket, boost::system::error_code& ec); - - // Start the asynchronous read or write operation. - BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, - reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); - - // Start the asynchronous accept operation. - BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, bool peer_is_open); - - // Start the asynchronous connect operation. - BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, - reactor_op* op, bool is_continuation, - const socket_addr_type* addr, size_t addrlen); - - // The selector that performs event demultiplexing for the service. - reactor& reactor_; - - // Cached success value to avoid accessing category singleton. - const boost::system::error_code success_ec_; -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext.hpp deleted file mode 100644 index 7254ccd..0000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext.hpp +++ /dev/null @@ -1,508 +0,0 @@ -// -// detail/reactive_socket_service_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext : - public execution_context_service_base >, - public reactive_socket_service_base_ext -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext(execution_context& context) - : execution_context_service_base< - reactive_socket_service_ext >(context), - reactive_socket_service_base_ext(context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext&, - typename reactive_socket_service_ext< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - destination, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(success_ec_, impl.socket_, protocol, buffers, - sender_endpoint, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_move_accept(implementation_type& impl, - const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, peer_io_ex, impl.socket_, impl.state_, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext_local.hpp deleted file mode 100644 index 8ac3265..0000000 --- a/implementation/helper/1.76/boost/asio/detail/reactive_socket_service_ext_local.hpp +++ /dev/null @@ -1,508 +0,0 @@ -// -// detail/reactive_socket_service_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if !defined(BOOST_ASIO_HAS_IOCP) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { - -template -class reactive_socket_service_ext_local : - public execution_context_service_base >, - public reactive_socket_service_base_ext_local -{ -public: - // The protocol type. - typedef Protocol protocol_type; - - // The endpoint type. - typedef typename Protocol::endpoint endpoint_type; - - // The native type of a socket. - typedef socket_type native_handle_type; - - // The implementation type of the socket. - struct implementation_type : - reactive_socket_service_base_ext_local::base_implementation_type - { - // Default constructor. - implementation_type() - : protocol_(endpoint_type().protocol()) - { - } - - // The protocol associated with the socket. - protocol_type protocol_; - }; - - // Constructor. - reactive_socket_service_ext_local(execution_context& context) - : execution_context_service_base< - reactive_socket_service_ext_local >(context), - reactive_socket_service_base_ext_local(context) - { - } - - // Destroy all user-defined handler objects owned by the service. - void shutdown() - { - this->base_shutdown(); - } - - // Move-construct a new socket implementation. - void move_construct(implementation_type& impl, - implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-assign from another socket implementation. - void move_assign(implementation_type& impl, - reactive_socket_service_base_ext_local& other_service, - implementation_type& other_impl) - { - this->base_move_assign(impl, other_service, other_impl); - - impl.protocol_ = other_impl.protocol_; - other_impl.protocol_ = endpoint_type().protocol(); - } - - // Move-construct a new socket implementation from another protocol type. - template - void converting_move_construct(implementation_type& impl, - reactive_socket_service_ext_local&, - typename reactive_socket_service_ext_local< - Protocol1>::implementation_type& other_impl) - { - this->base_move_construct(impl, other_impl); - - impl.protocol_ = protocol_type(other_impl.protocol_); - other_impl.protocol_ = typename Protocol1::endpoint().protocol(); - } - - // Open a new socket implementation. - boost::system::error_code open(implementation_type& impl, - const protocol_type& protocol, boost::system::error_code& ec) - { - if (!do_open(impl, protocol.family(), - protocol.type(), protocol.protocol(), ec)) - impl.protocol_ = protocol; - return ec; - } - - // Assign a native socket to a socket implementation. - boost::system::error_code assign(implementation_type& impl, - const protocol_type& protocol, const native_handle_type& native_socket, - boost::system::error_code& ec) - { - if (!do_assign(impl, protocol.type(), native_socket, ec)) - impl.protocol_ = protocol; - return ec; - } - - // Get the native socket representation. - native_handle_type native_handle(implementation_type& impl) - { - return impl.socket_; - } - - // Bind the socket to the specified local endpoint. - boost::system::error_code bind(implementation_type& impl, - const endpoint_type& endpoint, boost::system::error_code& ec) - { - socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code set_option(implementation_type& impl, - const Option& option, boost::system::error_code& ec) - { - socket_ops::setsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), option.size(impl.protocol_), ec); - return ec; - } - - // Set a socket option. - template - boost::system::error_code get_option(const implementation_type& impl, - Option& option, boost::system::error_code& ec) const - { - std::size_t size = option.size(impl.protocol_); - socket_ops::getsockopt(impl.socket_, impl.state_, - option.level(impl.protocol_), option.name(impl.protocol_), - option.data(impl.protocol_), &size, ec); - if (!ec) - option.resize(impl.protocol_, size); - return ec; - } - - // Get the local endpoint. - endpoint_type local_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Get the remote endpoint. - endpoint_type remote_endpoint(const implementation_type& impl, - boost::system::error_code& ec) const - { - endpoint_type endpoint; - std::size_t addr_len = endpoint.capacity(); - if (socket_ops::getpeername(impl.socket_, - endpoint.data(), &addr_len, false, ec)) - return endpoint_type(); - endpoint.resize(addr_len); - return endpoint; - } - - // Disable sends or receives on the socket. - boost::system::error_code shutdown(base_implementation_type& impl, - socket_base::shutdown_type what, boost::system::error_code& ec) - { - socket_ops::shutdown(impl.socket_, what, ec); - return ec; - } - - // Send a datagram to the specified endpoint. Returns the number of bytes - // sent. - template - size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - return socket_ops::sync_sendto(impl.socket_, impl.state_, - bufs.buffers(), bufs.count(), flags, - destination.data(), destination.size(), ec); - } - - // Wait until data can be sent without blocking. - size_t send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_write(impl.socket_, impl.state_, -1, ec); - - return 0; - } - - // Start an asynchronous send. The data being sent must be valid for the - // lifetime of the asynchronous operation. - template - void async_send_to(implementation_type& impl, - const ConstBufferSequence& buffers, - const endpoint_type& destination, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_sendto_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, buffers, - destination, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to")); - - start_op(impl, reactor::write_op, p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Start an asynchronous wait until data can be sent without blocking. - template - void async_send_to(implementation_type& impl, const null_buffers&, - const endpoint_type&, socket_base::message_flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_send_to(null_buffers)")); - - start_op(impl, reactor::write_op, p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Receive a datagram with the endpoint of the sender. Returns the number of - // bytes received. - template - size_t receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - boost::system::error_code& ec) - { - buffer_sequence_adapter bufs(buffers); - - std::size_t addr_len = sender_endpoint.capacity(); - std::size_t bytes_recvd = socket_ops::sync_recvfrom( - impl.socket_, impl.state_, bufs.buffers(), bufs.count(), - flags, sender_endpoint.data(), &addr_len, ec); - - if (!ec) - sender_endpoint.resize(addr_len); - - return bytes_recvd; - } - - // Wait until data can be received without blocking. - size_t receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags, - boost::system::error_code& ec) - { - // Wait for socket to become ready. - socket_ops::poll_read(impl.socket_, impl.state_, -1, ec); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - return 0; - } - - // Start an asynchronous receive. The buffer for the data being received and - // the sender_endpoint object must both be valid for the lifetime of the - // asynchronous operation. - template - void async_receive_from(implementation_type& impl, - const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, - socket_base::message_flags flags, Handler& handler, - const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_recvfrom_op_ext_local op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - int protocol = impl.protocol_.type(); - p.p = new (p.v) op(success_ec_, impl.socket_, protocol, buffers, - sender_endpoint, flags, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from")); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, true, false); - p.v = p.p = 0; - } - - // Wait until data can be received without blocking. - template - void async_receive_from(implementation_type& impl, const null_buffers&, - endpoint_type& sender_endpoint, socket_base::message_flags flags, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_null_buffers_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_receive_from(null_buffers)")); - - // Reset endpoint since it can be given no sensible value at this time. - sender_endpoint = endpoint_type(); - - start_op(impl, - (flags & socket_base::message_out_of_band) - ? reactor::except_op : reactor::read_op, - p.p, is_continuation, false, false); - p.v = p.p = 0; - } - - // Accept a new connection. - template - boost::system::error_code accept(implementation_type& impl, - Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) - { - // We cannot accept a socket that is already open. - if (peer.is_open()) - { - ec = boost::asio::error::already_open; - return ec; - } - - std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; - socket_holder new_socket(socket_ops::sync_accept(impl.socket_, - impl.state_, peer_endpoint ? peer_endpoint->data() : 0, - peer_endpoint ? &addr_len : 0, ec)); - - // On success, assign new connection to peer socket object. - if (new_socket.get() != invalid_socket) - { - if (peer_endpoint) - peer_endpoint->resize(addr_len); - peer.assign(impl.protocol_, new_socket.get(), ec); - if (!ec) - new_socket.release(); - } - - return ec; - } - - // Start an asynchronous accept. The peer and peer_endpoint objects must be - // valid until the accept's handler is invoked. - template - void async_accept(implementation_type& impl, Socket& peer, - endpoint_type* peer_endpoint, Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, impl.state_, peer, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, peer.is_open()); - p.v = p.p = 0; - } - -#if defined(BOOST_ASIO_HAS_MOVE) - // Start an asynchronous accept. The peer_endpoint object must be valid until - // the accept's handler is invoked. - template - void async_move_accept(implementation_type& impl, - const PeerIoExecutor& peer_io_ex, endpoint_type* peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_move_accept_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, peer_io_ex, impl.socket_, impl.state_, - impl.protocol_, peer_endpoint, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_accept")); - - start_accept_op(impl, p.p, is_continuation, false); - p.v = p.p = 0; - } -#endif // defined(BOOST_ASIO_HAS_MOVE) - - // Connect the socket to the specified endpoint. - boost::system::error_code connect(implementation_type& impl, - const endpoint_type& peer_endpoint, boost::system::error_code& ec) - { - socket_ops::sync_connect(impl.socket_, - peer_endpoint.data(), peer_endpoint.size(), ec); - return ec; - } - - // Start an asynchronous connect. - template - void async_connect(implementation_type& impl, - const endpoint_type& peer_endpoint, - Handler& handler, const IoExecutor& io_ex) - { - bool is_continuation = - boost_asio_handler_cont_helpers::is_continuation(handler); - - // Allocate and construct an operation to wrap the handler. - typedef reactive_socket_connect_op op; - typename op::ptr p = { boost::asio::detail::addressof(handler), - op::ptr::allocate(handler), 0 }; - p.p = new (p.v) op(success_ec_, impl.socket_, handler, io_ex); - - BOOST_ASIO_HANDLER_CREATION((reactor_.context(), *p.p, "socket", - &impl, impl.socket_, "async_connect")); - - start_connect_op(impl, p.p, is_continuation, - peer_endpoint.data(), peer_endpoint.size()); - p.v = p.p = 0; - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#endif // !defined(BOOST_ASIO_HAS_IOCP) - -#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/1.76/boost/asio/detail/reactor_op_ext.hpp deleted file mode 100644 index 697cd9f..0000000 --- a/implementation/helper/1.76/boost/asio/detail/reactor_op_ext.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// detail/reactor_op_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext - : public reactor_op -{ -public: - // The destination address - boost::asio::ip::address da_; - - reactor_op_ext(const boost::system::error_code& success_ec, - perform_func_type perform_func, func_type complete_func) - : reactor_op(success_ec, perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/reactor_op_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/reactor_op_ext_local.hpp deleted file mode 100644 index 3d9ae5f..0000000 --- a/implementation/helper/1.76/boost/asio/detail/reactor_op_ext_local.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// detail/reactor_op_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { - -class reactor_op_ext_local - : public reactor_op -{ -public: - // Credentials - std::uint32_t uid_; - std::uint32_t gid_; - - reactor_op_ext_local(const boost::system::error_code& success_ec, - perform_func_type perform_func, func_type complete_func) - : reactor_op(success_ec, perform_func, complete_func) - { - } -}; - -} // namespace detail -} // namespace asio -} // namespace boost - -#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/1.76/boost/asio/detail/socket_ops_ext.hpp deleted file mode 100644 index 9285fed..0000000 --- a/implementation/helper/1.76/boost/asio/detail/socket_ops_ext.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// detail/socket_ops_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - boost::asio::ip::address& da); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - boost::asio::ip::address& da); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - boost::asio::ip::address& da); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/1.76/boost/asio/detail/socket_ops_ext_local.hpp b/implementation/helper/1.76/boost/asio/detail/socket_ops_ext_local.hpp deleted file mode 100644 index a937bb6..0000000 --- a/implementation/helper/1.76/boost/asio/detail/socket_ops_ext_local.hpp +++ /dev/null @@ -1,95 +0,0 @@ -// -// detail/socket_ops_ext_local.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP -#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace detail { -namespace socket_ops { - -BOOST_ASIO_DECL signed_size_type recv(socket_type s, buf* bufs, - size_t count, int flags, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recv(socket_type s, state_type state, buf* bufs, - size_t count, int flags, bool all_empty, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recv(state_type state, - const weak_cancel_token_type& cancel_token, bool all_empty, - boost::system::error_code& ec, size_t bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recv(socket_type s, - buf* bufs, size_t count, int flags, bool is_stream, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, - size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, - buf* bufs, size_t count, int flags, socket_addr_type* addr, - std::size_t* addrlen, boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#if defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL void complete_iocp_recvfrom( - const weak_cancel_token_type& cancel_token, - boost::system::error_code& ec, - std::uint32_t& uid, std::uint32_t& gid); - -#else // defined(BOOST_ASIO_HAS_IOCP) - -BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, - buf* bufs, size_t count, int flags, - socket_addr_type* addr, std::size_t* addrlen, - boost::system::error_code& ec, size_t& bytes_transferred, - std::uint32_t& uid, std::uint32_t& gid); - -#endif // defined(BOOST_ASIO_HAS_IOCP) - - -} // namespace socket_ops -} // namespace detail -} // namespace asio -} // namespace boost - -#include - -#if defined(BOOST_ASIO_HEADER_ONLY) -# include -#endif // defined(BOOST_ASIO_HEADER_ONLY) - -#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP diff --git a/implementation/helper/1.76/boost/asio/ip/udp_ext.hpp b/implementation/helper/1.76/boost/asio/ip/udp_ext.hpp deleted file mode 100644 index 6ce2ac4..0000000 --- a/implementation/helper/1.76/boost/asio/ip/udp_ext.hpp +++ /dev/null @@ -1,115 +0,0 @@ -// -// ip/udp_ext.hpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (C) 2016-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_IP_UDP_EXT_HPP -#define BOOST_ASIO_IP_UDP_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace ip { - -/// Encapsulates the flags needed for UDP. -/** - * The boost::asio::ip::udp_ext class contains flags necessary for UDP sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol, InternetProtocol. - */ -class udp_ext -{ -public: - /// The type of a UDP endpoint. - typedef basic_endpoint endpoint; - - /// Construct to represent the IPv4 UDP protocol. - static udp_ext v4() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET)); - } - - /// Construct to represent the IPv6 UDP protocol. - static udp_ext v6() - { - return udp_ext(BOOST_ASIO_OS_DEF(AF_INET6)); - } - - /// Obtain an identifier for the type of the protocol. - int type() const - { - return BOOST_ASIO_OS_DEF(SOCK_DGRAM); - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return BOOST_ASIO_OS_DEF(IPPROTO_UDP); - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return family_; - } - - /// The UDP socket type. - typedef basic_datagram_socket_ext socket; - - /// The UDP resolver type. - typedef basic_resolver resolver; - - /// Compare two protocols for equality. - friend bool operator==(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ == p2.family_; - } - - /// Compare two protocols for inequality. - friend bool operator!=(const udp_ext& p1, const udp_ext& p2) - { - return p1.family_ != p2.family_; - } - -private: - // Construct with a specific family. - explicit udp_ext(int protocol_family) - : family_(protocol_family) - { - } - - int family_; -}; - -} // namespace ip -} // namespace asio -} // namespace boost - -#include - -#endif // BOOST_ASIO_IP_UDP_EXT_HPP diff --git a/implementation/helper/1.76/boost/asio/local/stream_protocol_ext.hpp b/implementation/helper/1.76/boost/asio/local/stream_protocol_ext.hpp deleted file mode 100644 index 7c57c62..0000000 --- a/implementation/helper/1.76/boost/asio/local/stream_protocol_ext.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// local/stream_protocol_ext.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// Copyright (c) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP -#define BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include - -#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ - || defined(GENERATING_DOCUMENTATION) - -#include -#include -#include -#include -#include - -#include - -namespace boost { -namespace asio { -namespace local { - -/// Encapsulates the flags needed for stream-oriented UNIX sockets. -/** - * The boost::asio::local::stream_protocol class contains flags necessary for - * stream-oriented UNIX domain sockets. - * - * @par Thread Safety - * @e Distinct @e objects: Safe.@n - * @e Shared @e objects: Safe. - * - * @par Concepts: - * Protocol. - */ -class stream_protocol_ext -{ -public: - /// Obtain an identifier for the type of the protocol. - int type() const - { - return SOCK_STREAM; - } - - /// Obtain an identifier for the protocol. - int protocol() const - { - return 0; - } - - /// Obtain an identifier for the protocol family. - int family() const - { - return AF_UNIX; - } - - /// The type of a UNIX domain endpoint. - typedef basic_endpoint endpoint; - - /// The UNIX domain socket type. - typedef basic_stream_socket_ext socket; - - /// The UNIX domain acceptor type. - typedef basic_socket_acceptor_ext acceptor; - -#if !defined(BOOST_ASIO_NO_IOSTREAM) - /// The UNIX domain iostream type. - typedef basic_socket_iostream iostream; -#endif // !defined(BOOST_ASIO_NO_IOSTREAM) -}; - -} // namespace local -} // namespace asio -} // namespace boost - -#include - -#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) - // || defined(GENERATING_DOCUMENTATION) - -#endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP diff --git a/implementation/helper/boost/asio/basic_datagram_socket_ext.hpp b/implementation/helper/boost/asio/basic_datagram_socket_ext.hpp new file mode 100644 index 0000000..43b2d93 --- /dev/null +++ b/implementation/helper/boost/asio/basic_datagram_socket_ext.hpp @@ -0,0 +1,954 @@ +// +// basic_datagram_socket_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP +#define BOOST_ASIO_BASIC_DATAGRAM_SOCKET_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { + +/// Provides datagram-oriented socket functionality. +/** + * The basic_datagram_socket class template provides asynchronous and blocking + * datagram-oriented socket functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + */ +template > +class basic_datagram_socket_ext + : public basic_socket +{ +public: + /// (Deprecated: Use native_handle_type.) The native representation of a + /// socket. + typedef typename DatagramSocketService::native_handle_type native_type; + + /// The native representation of a socket. + typedef typename DatagramSocketService::native_handle_type native_handle_type; + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// Construct a basic_datagram_socket without opening it. + /** + * This constructor creates a datagram socket without opening it. The open() + * function must be called before data can be sent or received on the socket. + * + * @param io_service The io_service object that the datagram socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + */ + explicit basic_datagram_socket_ext(boost::asio::io_service& io_service) + : basic_socket(io_service) + { + } + + /// Construct and open a basic_datagram_socket. + /** + * This constructor creates and opens a datagram socket. + * + * @param io_service The io_service object that the datagram socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_datagram_socket_ext(boost::asio::io_service& io_service, + const protocol_type& protocol) + : basic_socket(io_service, protocol) + { + } + + /// Construct a basic_datagram_socket, opening it and binding it to the given + /// local endpoint. + /** + * This constructor creates a datagram socket and automatically opens it bound + * to the specified endpoint on the local machine. The protocol used is the + * protocol associated with the given endpoint. + * + * @param io_service The io_service object that the datagram socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + * + * @param endpoint An endpoint on the local machine to which the datagram + * socket will be bound. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_datagram_socket_ext(boost::asio::io_service& io_service, + const endpoint_type& endpoint) + : basic_socket(io_service, endpoint) + { + } + + /// Construct a basic_datagram_socket on an existing native socket. + /** + * This constructor creates a datagram socket object to hold an existing + * native socket. + * + * @param io_service The io_service object that the datagram socket will use + * to dispatch handlers for any asynchronous operations performed on the + * socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_socket The new underlying socket implementation. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_datagram_socket_ext(boost::asio::io_service& io_service, + const protocol_type& protocol, const native_handle_type& native_socket) + : basic_socket( + io_service, protocol, native_socket) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_datagram_socket from another. + /** + * This constructor moves a datagram socket from one object to another. + * + * @param other The other basic_datagram_socket object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_datagram_socket(io_service&) constructor. + */ + basic_datagram_socket_ext(basic_datagram_socket_ext&& other) + : basic_socket( + BOOST_ASIO_MOVE_CAST(basic_datagram_socket_ext)(other)) + { + } + + /// Move-assign a basic_datagram_socket from another. + /** + * This assignment operator moves a datagram socket from one object to + * another. + * + * @param other The other basic_datagram_socket object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_datagram_socket(io_service&) constructor. + */ + basic_datagram_socket_ext& operator=(basic_datagram_socket_ext&& other) + { + basic_socket::operator=( + BOOST_ASIO_MOVE_CAST(basic_datagram_socket_ext)(other)); + return *this; + } + + /// Move-construct a basic_datagram_socket from a socket of another protocol + /// type. + /** + * This constructor moves a datagram socket from one object to another. + * + * @param other The other basic_datagram_socket object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_datagram_socket(io_service&) constructor. + */ + template + basic_datagram_socket_ext( + basic_datagram_socket_ext&& other, + typename enable_if::value>::type* = 0) + : basic_socket( + BOOST_ASIO_MOVE_CAST2(basic_datagram_socket_ext< + Protocol1, DatagramSocketService1>)(other)) + { + } + + /// Move-assign a basic_datagram_socket from a socket of another protocol + /// type. + /** + * This assignment operator moves a datagram socket from one object to + * another. + * + * @param other The other basic_datagram_socket object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_datagram_socket(io_service&) constructor. + */ + template + typename enable_if::value, + basic_datagram_socket_ext>::type& operator=( + basic_datagram_socket_ext&& other) + { + basic_socket::operator=( + BOOST_ASIO_MOVE_CAST2(basic_datagram_socket_ext< + Protocol1, DatagramSocketService1>)(other)); + return *this; + } +#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Send some data on a connected socket. + /** + * This function is used to send data on the datagram socket. The function + * call will block until the data has been sent successfully or an error + * occurs. + * + * @param buffers One ore more data buffers to be sent on the socket. + * + * @returns The number of bytes sent. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The send operation can only be used with a connected socket. Use + * the send_to function to send data on an unconnected datagram socket. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code socket.send(boost::asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send(const ConstBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = this->get_service().send( + this->get_implementation(), buffers, 0, ec); + boost::asio::detail::throw_error(ec, "send"); + return s; + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the datagram socket. The function + * call will block until the data has been sent successfully or an error + * occurs. + * + * @param buffers One ore more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @returns The number of bytes sent. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The send operation can only be used with a connected socket. Use + * the send_to function to send data on an unconnected datagram socket. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags) + { + boost::system::error_code ec; + std::size_t s = this->get_service().send( + this->get_implementation(), buffers, flags, ec); + boost::asio::detail::throw_error(ec, "send"); + return s; + } + + /// Send some data on a connected socket. + /** + * This function is used to send data on the datagram socket. The function + * call will block until the data has been sent successfully or an error + * occurs. + * + * @param buffers One or more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes sent. + * + * @note The send operation can only be used with a connected socket. Use + * the send_to function to send data on an unconnected datagram socket. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return this->get_service().send( + this->get_implementation(), buffers, flags, ec); + } + + /// Start an asynchronous send on a connected socket. + /** + * This function is used to asynchronously send data on the datagram socket. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The async_send operation can only be used with a connected socket. + * Use the async_send_to function to send data on an unconnected datagram + * socket. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_send(boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (boost::system::error_code, std::size_t)) + async_send(const ConstBufferSequence& buffers, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + return this->get_service().async_send(this->get_implementation(), + buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Start an asynchronous send on a connected socket. + /** + * This function is used to asynchronously send data on the datagram socket. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The async_send operation can only be used with a connected socket. + * Use the async_send_to function to send data on an unconnected datagram + * socket. + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (boost::system::error_code, std::size_t)) + async_send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + return this->get_service().async_send(this->get_implementation(), + buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Send a datagram to the specified endpoint. + /** + * This function is used to send a datagram to the specified remote endpoint. + * The function call will block until the data has been sent successfully or + * an error occurs. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * + * @param destination The remote endpoint to which the data will be sent. + * + * @returns The number of bytes sent. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * boost::asio::ip::udp::endpoint destination( + * boost::asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.send_to(boost::asio::buffer(data, size), destination); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination) + { + boost::system::error_code ec; + std::size_t s = this->get_service().send_to( + this->get_implementation(), buffers, destination, 0, ec); + boost::asio::detail::throw_error(ec, "send_to"); + return s; + } + + /// Send a datagram to the specified endpoint. + /** + * This function is used to send a datagram to the specified remote endpoint. + * The function call will block until the data has been sent successfully or + * an error occurs. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * + * @param destination The remote endpoint to which the data will be sent. + * + * @param flags Flags specifying how the send call is to be made. + * + * @returns The number of bytes sent. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags) + { + boost::system::error_code ec; + std::size_t s = this->get_service().send_to( + this->get_implementation(), buffers, destination, flags, ec); + boost::asio::detail::throw_error(ec, "send_to"); + return s; + } + + /// Send a datagram to the specified endpoint. + /** + * This function is used to send a datagram to the specified remote endpoint. + * The function call will block until the data has been sent successfully or + * an error occurs. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * + * @param destination The remote endpoint to which the data will be sent. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes sent. + */ + template + std::size_t send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + boost::system::error_code& ec) + { + return this->get_service().send_to(this->get_implementation(), + buffers, destination, flags, ec); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send a datagram to the specified + * remote endpoint. The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param destination The remote endpoint to which the data will be sent. + * Copies will be made of the endpoint as required. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * boost::asio::ip::udp::endpoint destination( + * boost::asio::ip::address::from_string("1.2.3.4"), 12345); + * socket.async_send_to( + * boost::asio::buffer(data, size), destination, handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (boost::system::error_code, std::size_t)) + async_send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + return this->get_service().async_send_to( + this->get_implementation(), buffers, destination, 0, + BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send a datagram to the specified + * remote endpoint. The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent to the remote endpoint. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param destination The remote endpoint to which the data will be sent. + * Copies will be made of the endpoint as required. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (boost::system::error_code, std::size_t)) + async_send_to(const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + return this->get_service().async_send_to( + this->get_implementation(), buffers, destination, flags, + BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the datagram socket. The function + * call will block until data has been received successfully or an error + * occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @returns The number of bytes received. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The receive operation can only be used with a connected socket. Use + * the receive_from function to receive data on an unconnected datagram + * socket. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code socket.receive(boost::asio::buffer(data, size)); @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive(const MutableBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, 0, ec); + boost::asio::detail::throw_error(ec, "receive"); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the datagram socket. The function + * call will block until data has been received successfully or an error + * occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @returns The number of bytes received. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The receive operation can only be used with a connected socket. Use + * the receive_from function to receive data on an unconnected datagram + * socket. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags) + { + boost::system::error_code ec; + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, flags, ec); + boost::asio::detail::throw_error(ec, "receive"); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the datagram socket. The function + * call will block until data has been received successfully or an error + * occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes received. + * + * @note The receive operation can only be used with a connected socket. Use + * the receive_from function to receive data on an unconnected datagram + * socket. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return this->get_service().receive( + this->get_implementation(), buffers, flags, ec); + } + + /// Start an asynchronous receive on a connected socket. + /** + * This function is used to asynchronously receive data from the datagram + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The async_receive operation can only be used with a connected socket. + * Use the async_receive_from function to receive data on an unconnected + * datagram socket. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.async_receive(boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (boost::system::error_code, std::size_t)) + async_receive(const MutableBufferSequence& buffers, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; + + return this->get_service().async_receive(this->get_implementation(), + buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + } + + /// Start an asynchronous receive on a connected socket. + /** + * This function is used to asynchronously receive data from the datagram + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The async_receive operation can only be used with a connected socket. + * Use the async_receive_from function to receive data on an unconnected + * datagram socket. + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (boost::system::error_code, std::size_t)) + async_receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; + + return this->get_service().async_receive(this->get_implementation(), + buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + } + + /// Receive a datagram with the endpoint of the sender. + /** + * This function is used to receive a datagram. The function call will block + * until data has been received successfully or an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. + * + * @returns The number of bytes received. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * boost::asio::ip::udp::endpoint sender_endpoint; + * socket.receive_from( + * boost::asio::buffer(data, size), sender_endpoint); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint) + { + boost::system::error_code ec; + std::size_t s = this->get_service().receive_from( + this->get_implementation(), buffers, sender_endpoint, 0, ec); + boost::asio::detail::throw_error(ec, "receive_from"); + return s; + } + + /// Receive a datagram with the endpoint of the sender. + /** + * This function is used to receive a datagram. The function call will block + * until data has been received successfully or an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @returns The number of bytes received. + * + * @throws boost::system::system_error Thrown on failure. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags) + { + boost::system::error_code ec; + std::size_t s = this->get_service().receive_from( + this->get_implementation(), buffers, sender_endpoint, flags, ec); + boost::asio::detail::throw_error(ec, "receive_from"); + return s; + } + + /// Receive a datagram with the endpoint of the sender. + /** + * This function is used to receive a datagram. The function call will block + * until data has been received successfully or an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes received. + */ + template + std::size_t receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + boost::system::error_code& ec) + { + return this->get_service().receive_from(this->get_implementation(), + buffers, sender_endpoint, flags, ec); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive a datagram. The function + * call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. Ownership of the sender_endpoint object + * is retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code socket.async_receive_from( + * boost::asio::buffer(data, size), sender_endpoint, handler); @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (boost::system::error_code, std::size_t, boost::asio::ip::address)) + async_receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; + + return this->get_service().async_receive_from( + this->get_implementation(), buffers, sender_endpoint, 0, + BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive a datagram. The function + * call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param sender_endpoint An endpoint object that receives the endpoint of + * the remote sender of the datagram. Ownership of the sender_endpoint object + * is retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (boost::system::error_code, std::size_t, boost::asio::ip::address)) + async_receive_from(const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK_EXT(ReadHandler, handler) type_check; + + return this->get_service().async_receive_from( + this->get_implementation(), buffers, sender_endpoint, flags, + BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + } +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP diff --git a/implementation/helper/boost/asio/basic_socket_acceptor_ext.hpp b/implementation/helper/boost/asio/basic_socket_acceptor_ext.hpp new file mode 100644 index 0000000..4af4bac --- /dev/null +++ b/implementation/helper/boost/asio/basic_socket_acceptor_ext.hpp @@ -0,0 +1,1139 @@ +// +// basic_socket_acceptor_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP +#define BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { + +/// Provides the ability to accept new connections. +/** + * The basic_socket_acceptor_ext class template is used for accepting new socket + * connections. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Example + * Opening a socket acceptor with the SO_REUSEADDR option enabled: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port); + * acceptor.open(endpoint.protocol()); + * acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true)); + * acceptor.bind(endpoint); + * acceptor.listen(); + * @endcode + */ +template > +class basic_socket_acceptor_ext + : public basic_io_object, + public socket_base +{ +public: + /// (Deprecated: Use native_handle_type.) The native representation of an + /// acceptor. + typedef typename SocketAcceptorService::native_handle_type native_type; + + /// The native representation of an acceptor. + typedef typename SocketAcceptorService::native_handle_type native_handle_type; + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// Construct an acceptor without opening it. + /** + * This constructor creates an acceptor without opening it to listen for new + * connections. The open() function must be called before the acceptor can + * accept new socket connections. + * + * @param io_service The io_service object that the acceptor will use to + * dispatch handlers for any asynchronous operations performed on the + * acceptor. + */ + explicit basic_socket_acceptor_ext(boost::asio::io_service& io_service) + : basic_io_object(io_service) + { + } + + /// Construct an open acceptor. + /** + * This constructor creates an acceptor and automatically opens it. + * + * @param io_service The io_service object that the acceptor will use to + * dispatch handlers for any asynchronous operations performed on the + * acceptor. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_socket_acceptor_ext(boost::asio::io_service& io_service, + const protocol_type& protocol) + : basic_io_object(io_service) + { + boost::system::error_code ec; + this->get_service().open(this->get_implementation(), protocol, ec); + boost::asio::detail::throw_error(ec, "open"); + } + + /// Construct an acceptor opened on the given endpoint. + /** + * This constructor creates an acceptor and automatically opens it to listen + * for new connections on the specified endpoint. + * + * @param io_service The io_service object that the acceptor will use to + * dispatch handlers for any asynchronous operations performed on the + * acceptor. + * + * @param endpoint An endpoint on the local machine on which the acceptor + * will listen for new connections. + * + * @param reuse_addr Whether the constructor should set the socket option + * socket_base::reuse_address. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note This constructor is equivalent to the following code: + * @code + * basic_socket_acceptor_ext acceptor(io_service); + * acceptor.open(endpoint.protocol()); + * if (reuse_addr) + * acceptor.set_option(socket_base::reuse_address(true)); + * acceptor.bind(endpoint); + * acceptor.listen(listen_backlog); + * @endcode + */ + basic_socket_acceptor_ext(boost::asio::io_service& io_service, + const endpoint_type& endpoint, bool reuse_addr = true) + : basic_io_object(io_service) + { + boost::system::error_code ec; + const protocol_type protocol = endpoint.protocol(); + this->get_service().open(this->get_implementation(), protocol, ec); + boost::asio::detail::throw_error(ec, "open"); + if (reuse_addr) + { + this->get_service().set_option(this->get_implementation(), + socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "set_option"); + } + this->get_service().bind(this->get_implementation(), endpoint, ec); + boost::asio::detail::throw_error(ec, "bind"); + this->get_service().listen(this->get_implementation(), + socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec, "listen"); + } + + /// Construct a basic_socket_acceptor_ext on an existing native acceptor. + /** + * This constructor creates an acceptor object to hold an existing native + * acceptor. + * + * @param io_service The io_service object that the acceptor will use to + * dispatch handlers for any asynchronous operations performed on the + * acceptor. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_acceptor A native acceptor. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_socket_acceptor_ext(boost::asio::io_service& io_service, + const protocol_type& protocol, const native_handle_type& native_acceptor) + : basic_io_object(io_service) + { + boost::system::error_code ec; + this->get_service().assign(this->get_implementation(), + protocol, native_acceptor, ec); + boost::asio::detail::throw_error(ec, "assign"); + } + +#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_socket_acceptor_ext from another. + /** + * This constructor moves an acceptor from one object to another. + * + * @param other The other basic_socket_acceptor_ext object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_socket_acceptor_ext(io_service&) constructor. + */ + basic_socket_acceptor_ext(basic_socket_acceptor_ext&& other) + : basic_io_object( + BOOST_ASIO_MOVE_CAST(basic_socket_acceptor_ext)(other)) + { + } + + /// Move-assign a basic_socket_acceptor_ext from another. + /** + * This assignment operator moves an acceptor from one object to another. + * + * @param other The other basic_socket_acceptor_ext object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_socket_acceptor_ext(io_service&) constructor. + */ + basic_socket_acceptor_ext& operator=(basic_socket_acceptor_ext&& other) + { + basic_io_object::operator=( + BOOST_ASIO_MOVE_CAST(basic_socket_acceptor_ext)(other)); + return *this; + } + + // All socket acceptors have access to each other's implementations. + template + friend class basic_socket_acceptor_ext; + + /// Move-construct a basic_socket_acceptor_ext from an acceptor of another + /// protocol type. + /** + * This constructor moves an acceptor from one object to another. + * + * @param other The other basic_socket_acceptor_ext object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_socket(io_service&) constructor. + */ + template + basic_socket_acceptor_ext( + basic_socket_acceptor_ext&& other, + typename enable_if::value>::type* = 0) + : basic_io_object(other.get_io_service()) + { + this->get_service().template converting_move_construct( + this->get_implementation(), other.get_implementation()); + } + + /// Move-assign a basic_socket_acceptor_ext from an acceptor of another protocol + /// type. + /** + * This assignment operator moves an acceptor from one object to another. + * + * @param other The other basic_socket_acceptor_ext object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_socket(io_service&) constructor. + */ + template + typename enable_if::value, + basic_socket_acceptor_ext>::type& operator=( + basic_socket_acceptor_ext&& other) + { + basic_socket_acceptor_ext tmp(BOOST_ASIO_MOVE_CAST2(basic_socket_acceptor_ext< + Protocol1, SocketAcceptorService1>)(other)); + basic_io_object::operator=( + BOOST_ASIO_MOVE_CAST(basic_socket_acceptor_ext)(tmp)); + return *this; + } +#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Open the acceptor using the specified protocol. + /** + * This function opens the socket acceptor so that it will use the specified + * protocol. + * + * @param protocol An object specifying which protocol is to be used. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * acceptor.open(boost::asio::ip::tcp::v4()); + * @endcode + */ + void open(const protocol_type& protocol = protocol_type()) + { + boost::system::error_code ec; + this->get_service().open(this->get_implementation(), protocol, ec); + boost::asio::detail::throw_error(ec, "open"); + } + + /// Open the acceptor using the specified protocol. + /** + * This function opens the socket acceptor so that it will use the specified + * protocol. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::system::error_code ec; + * acceptor.open(boost::asio::ip::tcp::v4(), ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + boost::system::error_code open(const protocol_type& protocol, + boost::system::error_code& ec) + { + return this->get_service().open(this->get_implementation(), protocol, ec); + } + + /// Assigns an existing native acceptor to the acceptor. + /* + * This function opens the acceptor to hold an existing native acceptor. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param native_acceptor A native acceptor. + * + * @throws boost::system::system_error Thrown on failure. + */ + void assign(const protocol_type& protocol, + const native_handle_type& native_acceptor) + { + boost::system::error_code ec; + this->get_service().assign(this->get_implementation(), + protocol, native_acceptor, ec); + boost::asio::detail::throw_error(ec, "assign"); + } + + /// Assigns an existing native acceptor to the acceptor. + /* + * This function opens the acceptor to hold an existing native acceptor. + * + * @param protocol An object specifying which protocol is to be used. + * + * @param native_acceptor A native acceptor. + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code assign(const protocol_type& protocol, + const native_handle_type& native_acceptor, boost::system::error_code& ec) + { + return this->get_service().assign(this->get_implementation(), + protocol, native_acceptor, ec); + } + + /// Determine whether the acceptor is open. + bool is_open() const + { + return this->get_service().is_open(this->get_implementation()); + } + + /// Bind the acceptor to the given local endpoint. + /** + * This function binds the socket acceptor to the specified endpoint on the + * local machine. + * + * @param endpoint An endpoint on the local machine to which the socket + * acceptor will be bound. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); + * acceptor.open(endpoint.protocol()); + * acceptor.bind(endpoint); + * @endcode + */ + void bind(const endpoint_type& endpoint) + { + boost::system::error_code ec; + this->get_service().bind(this->get_implementation(), endpoint, ec); + boost::asio::detail::throw_error(ec, "bind"); + } + + /// Bind the acceptor to the given local endpoint. + /** + * This function binds the socket acceptor to the specified endpoint on the + * local machine. + * + * @param endpoint An endpoint on the local machine to which the socket + * acceptor will be bound. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), 12345); + * acceptor.open(endpoint.protocol()); + * boost::system::error_code ec; + * acceptor.bind(endpoint, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + boost::system::error_code bind(const endpoint_type& endpoint, + boost::system::error_code& ec) + { + return this->get_service().bind(this->get_implementation(), endpoint, ec); + } + + /// Place the acceptor into the state where it will listen for new + /// connections. + /** + * This function puts the socket acceptor into the state where it may accept + * new connections. + * + * @param backlog The maximum length of the queue of pending connections. + * + * @throws boost::system::system_error Thrown on failure. + */ + void listen(int backlog = socket_base::max_connections) + { + boost::system::error_code ec; + this->get_service().listen(this->get_implementation(), backlog, ec); + boost::asio::detail::throw_error(ec, "listen"); + } + + /// Place the acceptor into the state where it will listen for new + /// connections. + /** + * This function puts the socket acceptor into the state where it may accept + * new connections. + * + * @param backlog The maximum length of the queue of pending connections. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::system::error_code ec; + * acceptor.listen(boost::asio::socket_base::max_connections, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + boost::system::error_code listen(int backlog, boost::system::error_code& ec) + { + return this->get_service().listen(this->get_implementation(), backlog, ec); + } + + /// Close the acceptor. + /** + * This function is used to close the acceptor. Any asynchronous accept + * operations will be cancelled immediately. + * + * A subsequent call to open() is required before the acceptor can again be + * used to again perform socket accept operations. + * + * @throws boost::system::system_error Thrown on failure. + */ + void close() + { + boost::system::error_code ec; + this->get_service().close(this->get_implementation(), ec); + boost::asio::detail::throw_error(ec, "close"); + } + + /// Close the acceptor. + /** + * This function is used to close the acceptor. Any asynchronous accept + * operations will be cancelled immediately. + * + * A subsequent call to open() is required before the acceptor can again be + * used to again perform socket accept operations. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::system::error_code ec; + * acceptor.close(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + boost::system::error_code close(boost::system::error_code& ec) + { + return this->get_service().close(this->get_implementation(), ec); + } + + /// (Deprecated: Use native_handle().) Get the native acceptor representation. + /** + * This function may be used to obtain the underlying representation of the + * acceptor. This is intended to allow access to native acceptor functionality + * that is not otherwise provided. + */ + native_type native() + { + return this->get_service().native_handle(this->get_implementation()); + } + + /// Get the native acceptor representation. + /** + * This function may be used to obtain the underlying representation of the + * acceptor. This is intended to allow access to native acceptor functionality + * that is not otherwise provided. + */ + native_handle_type native_handle() + { + return this->get_service().native_handle(this->get_implementation()); + } + + /// Cancel all asynchronous operations associated with the acceptor. + /** + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the boost::asio::error::operation_aborted error. + * + * @throws boost::system::system_error Thrown on failure. + */ + void cancel() + { + boost::system::error_code ec; + this->get_service().cancel(this->get_implementation(), ec); + boost::asio::detail::throw_error(ec, "cancel"); + } + + /// Cancel all asynchronous operations associated with the acceptor. + /** + * This function causes all outstanding asynchronous connect, send and receive + * operations to finish immediately, and the handlers for cancelled operations + * will be passed the boost::asio::error::operation_aborted error. + * + * @param ec Set to indicate what error occurred, if any. + */ + boost::system::error_code cancel(boost::system::error_code& ec) + { + return this->get_service().cancel(this->get_implementation(), ec); + } + + /// Set an option on the acceptor. + /** + * This function is used to set an option on the acceptor. + * + * @param option The new option value to be set on the acceptor. + * + * @throws boost::system::system_error Thrown on failure. + * + * @sa SettableSocketOption @n + * boost::asio::socket_base::reuse_address + * boost::asio::socket_base::enable_connection_aborted + * + * @par Example + * Setting the SOL_SOCKET/SO_REUSEADDR option: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::acceptor::reuse_address option(true); + * acceptor.set_option(option); + * @endcode + */ + template + void set_option(const SettableSocketOption& option) + { + boost::system::error_code ec; + this->get_service().set_option(this->get_implementation(), option, ec); + boost::asio::detail::throw_error(ec, "set_option"); + } + + /// Set an option on the acceptor. + /** + * This function is used to set an option on the acceptor. + * + * @param option The new option value to be set on the acceptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa SettableSocketOption @n + * boost::asio::socket_base::reuse_address + * boost::asio::socket_base::enable_connection_aborted + * + * @par Example + * Setting the SOL_SOCKET/SO_REUSEADDR option: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::acceptor::reuse_address option(true); + * boost::system::error_code ec; + * acceptor.set_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + boost::system::error_code set_option(const SettableSocketOption& option, + boost::system::error_code& ec) + { + return this->get_service().set_option( + this->get_implementation(), option, ec); + } + + /// Get an option from the acceptor. + /** + * This function is used to get the current value of an option on the + * acceptor. + * + * @param option The option value to be obtained from the acceptor. + * + * @throws boost::system::system_error Thrown on failure. + * + * @sa GettableSocketOption @n + * boost::asio::socket_base::reuse_address + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::acceptor::reuse_address option; + * acceptor.get_option(option); + * bool is_set = option.get(); + * @endcode + */ + template + void get_option(GettableSocketOption& option) + { + boost::system::error_code ec; + this->get_service().get_option(this->get_implementation(), option, ec); + boost::asio::detail::throw_error(ec, "get_option"); + } + + /// Get an option from the acceptor. + /** + * This function is used to get the current value of an option on the + * acceptor. + * + * @param option The option value to be obtained from the acceptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa GettableSocketOption @n + * boost::asio::socket_base::reuse_address + * + * @par Example + * Getting the value of the SOL_SOCKET/SO_REUSEADDR option: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::acceptor::reuse_address option; + * boost::system::error_code ec; + * acceptor.get_option(option, ec); + * if (ec) + * { + * // An error occurred. + * } + * bool is_set = option.get(); + * @endcode + */ + template + boost::system::error_code get_option(GettableSocketOption& option, + boost::system::error_code& ec) + { + return this->get_service().get_option( + this->get_implementation(), option, ec); + } + + /// Perform an IO control command on the acceptor. + /** + * This function is used to execute an IO control command on the acceptor. + * + * @param command The IO control command to be performed on the acceptor. + * + * @throws boost::system::system_error Thrown on failure. + * + * @sa IoControlCommand @n + * boost::asio::socket_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); + * socket.io_control(command); + * @endcode + */ + template + void io_control(IoControlCommand& command) + { + boost::system::error_code ec; + this->get_service().io_control(this->get_implementation(), command, ec); + boost::asio::detail::throw_error(ec, "io_control"); + } + + /// Perform an IO control command on the acceptor. + /** + * This function is used to execute an IO control command on the acceptor. + * + * @param command The IO control command to be performed on the acceptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @sa IoControlCommand @n + * boost::asio::socket_base::non_blocking_io + * + * @par Example + * Getting the number of bytes ready to read: + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::acceptor::non_blocking_io command(true); + * boost::system::error_code ec; + * socket.io_control(command, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + boost::system::error_code io_control(IoControlCommand& command, + boost::system::error_code& ec) + { + return this->get_service().io_control( + this->get_implementation(), command, ec); + } + + /// Gets the non-blocking mode of the acceptor. + /** + * @returns @c true if the acceptor's synchronous operations will fail with + * boost::asio::error::would_block if they are unable to perform the requested + * operation immediately. If @c false, synchronous operations will block + * until complete. + * + * @note The non-blocking mode has no effect on the behaviour of asynchronous + * operations. Asynchronous operations will never fail with the error + * boost::asio::error::would_block. + */ + bool non_blocking() const + { + return this->get_service().non_blocking(this->get_implementation()); + } + + /// Sets the non-blocking mode of the acceptor. + /** + * @param mode If @c true, the acceptor's synchronous operations will fail + * with boost::asio::error::would_block if they are unable to perform the + * requested operation immediately. If @c false, synchronous operations will + * block until complete. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The non-blocking mode has no effect on the behaviour of asynchronous + * operations. Asynchronous operations will never fail with the error + * boost::asio::error::would_block. + */ + void non_blocking(bool mode) + { + boost::system::error_code ec; + this->get_service().non_blocking(this->get_implementation(), mode, ec); + boost::asio::detail::throw_error(ec, "non_blocking"); + } + + /// Sets the non-blocking mode of the acceptor. + /** + * @param mode If @c true, the acceptor's synchronous operations will fail + * with boost::asio::error::would_block if they are unable to perform the + * requested operation immediately. If @c false, synchronous operations will + * block until complete. + * + * @param ec Set to indicate what error occurred, if any. + * + * @note The non-blocking mode has no effect on the behaviour of asynchronous + * operations. Asynchronous operations will never fail with the error + * boost::asio::error::would_block. + */ + boost::system::error_code non_blocking( + bool mode, boost::system::error_code& ec) + { + return this->get_service().non_blocking( + this->get_implementation(), mode, ec); + } + + /// Gets the non-blocking mode of the native acceptor implementation. + /** + * This function is used to retrieve the non-blocking mode of the underlying + * native acceptor. This mode has no effect on the behaviour of the acceptor + * object's synchronous operations. + * + * @returns @c true if the underlying acceptor is in non-blocking mode and + * direct system calls may fail with boost::asio::error::would_block (or the + * equivalent system error). + * + * @note The current non-blocking mode is cached by the acceptor object. + * Consequently, the return value may be incorrect if the non-blocking mode + * was set directly on the native acceptor. + */ + bool native_non_blocking() const + { + return this->get_service().native_non_blocking(this->get_implementation()); + } + + /// Sets the non-blocking mode of the native acceptor implementation. + /** + * This function is used to modify the non-blocking mode of the underlying + * native acceptor. It has no effect on the behaviour of the acceptor object's + * synchronous operations. + * + * @param mode If @c true, the underlying acceptor is put into non-blocking + * mode and direct system calls may fail with boost::asio::error::would_block + * (or the equivalent system error). + * + * @throws boost::system::system_error Thrown on failure. If the @c mode is + * @c false, but the current value of @c non_blocking() is @c true, this + * function fails with boost::asio::error::invalid_argument, as the + * combination does not make sense. + */ + void native_non_blocking(bool mode) + { + boost::system::error_code ec; + this->get_service().native_non_blocking( + this->get_implementation(), mode, ec); + boost::asio::detail::throw_error(ec, "native_non_blocking"); + } + + /// Sets the non-blocking mode of the native acceptor implementation. + /** + * This function is used to modify the non-blocking mode of the underlying + * native acceptor. It has no effect on the behaviour of the acceptor object's + * synchronous operations. + * + * @param mode If @c true, the underlying acceptor is put into non-blocking + * mode and direct system calls may fail with boost::asio::error::would_block + * (or the equivalent system error). + * + * @param ec Set to indicate what error occurred, if any. If the @c mode is + * @c false, but the current value of @c non_blocking() is @c true, this + * function fails with boost::asio::error::invalid_argument, as the + * combination does not make sense. + */ + boost::system::error_code native_non_blocking( + bool mode, boost::system::error_code& ec) + { + return this->get_service().native_non_blocking( + this->get_implementation(), mode, ec); + } + + /// Get the local endpoint of the acceptor. + /** + * This function is used to obtain the locally bound endpoint of the acceptor. + * + * @returns An object that represents the local endpoint of the acceptor. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(); + * @endcode + */ + endpoint_type local_endpoint() const + { + boost::system::error_code ec; + endpoint_type ep = this->get_service().local_endpoint( + this->get_implementation(), ec); + boost::asio::detail::throw_error(ec, "local_endpoint"); + return ep; + } + + /// Get the local endpoint of the acceptor. + /** + * This function is used to obtain the locally bound endpoint of the acceptor. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns An object that represents the local endpoint of the acceptor. + * Returns a default-constructed endpoint object if an error occurred and the + * error handler did not throw an exception. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::system::error_code ec; + * boost::asio::ip::tcp::endpoint endpoint = acceptor.local_endpoint(ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + endpoint_type local_endpoint(boost::system::error_code& ec) const + { + return this->get_service().local_endpoint(this->get_implementation(), ec); + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer into the + * given socket. The function call will block until a new connection has been + * accepted successfully or an error occurs. + * + * @param peer The socket into which the new connection will be accepted. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::socket socket(io_service); + * acceptor.accept(socket); + * @endcode + */ + template + void accept(basic_socket& peer, + typename enable_if::value>::type* = 0) + { + boost::system::error_code ec; + this->get_service().accept(this->get_implementation(), + peer, static_cast(0), ec); + boost::asio::detail::throw_error(ec, "accept"); + } + + /// Accept a new connection. + /** + * This function is used to accept a new connection from a peer into the + * given socket. The function call will block until a new connection has been + * accepted successfully or an error occurs. + * + * @param peer The socket into which the new connection will be accepted. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::soocket socket(io_service); + * boost::system::error_code ec; + * acceptor.accept(socket, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + boost::system::error_code accept( + basic_socket& peer, + boost::system::error_code& ec, + typename enable_if::value>::type* = 0) + { + return this->get_service().accept(this->get_implementation(), + peer, static_cast(0), ec); + } + + /// Start an asynchronous accept. + /** + * This function is used to asynchronously accept a new connection into a + * socket. The function call always returns immediately. + * + * @param peer The socket into which the new connection will be accepted. + * Ownership of the peer object is retained by the caller, which must + * guarantee that it is valid until the handler is called. + * + * @param handler The handler to be called when the accept operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error // Result of operation. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @par Example + * @code + * void accept_handler(const boost::system::error_code& error) + * { + * if (!error) + * { + * // Accept succeeded. + * } + * } + * + * ... + * + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::socket socket(io_service); + * acceptor.async_accept(socket, accept_handler); + * @endcode + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, + void (boost::system::error_code)) + async_accept(basic_socket& peer, + BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, + typename enable_if::value>::type* = 0) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a AcceptHandler. + BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; + + return this->get_service().async_accept(this->get_implementation(), + peer, static_cast(0), + BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); + } + + /// Accept a new connection and obtain the endpoint of the peer + /** + * This function is used to accept a new connection from a peer into the + * given socket, and additionally provide the endpoint of the remote peer. + * The function call will block until a new connection has been accepted + * successfully or an error occurs. + * + * @param peer The socket into which the new connection will be accepted. + * + * @param peer_endpoint An endpoint object which will receive the endpoint of + * the remote peer. + * + * @throws boost::system::system_error Thrown on failure. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::endpoint endpoint; + * acceptor.accept(socket, endpoint); + * @endcode + */ + template + void accept(basic_socket& peer, + endpoint_type& peer_endpoint) + { + boost::system::error_code ec; + this->get_service().accept(this->get_implementation(), + peer, &peer_endpoint, ec); + boost::asio::detail::throw_error(ec, "accept"); + } + + /// Accept a new connection and obtain the endpoint of the peer + /** + * This function is used to accept a new connection from a peer into the + * given socket, and additionally provide the endpoint of the remote peer. + * The function call will block until a new connection has been accepted + * successfully or an error occurs. + * + * @param peer The socket into which the new connection will be accepted. + * + * @param peer_endpoint An endpoint object which will receive the endpoint of + * the remote peer. + * + * @param ec Set to indicate what error occurred, if any. + * + * @par Example + * @code + * boost::asio::ip::tcp::acceptor acceptor(io_service); + * ... + * boost::asio::ip::tcp::socket socket(io_service); + * boost::asio::ip::tcp::endpoint endpoint; + * boost::system::error_code ec; + * acceptor.accept(socket, endpoint, ec); + * if (ec) + * { + * // An error occurred. + * } + * @endcode + */ + template + boost::system::error_code accept( + basic_socket& peer, + endpoint_type& peer_endpoint, boost::system::error_code& ec) + { + return this->get_service().accept( + this->get_implementation(), peer, &peer_endpoint, ec); + } + + /// Start an asynchronous accept. + /** + * This function is used to asynchronously accept a new connection into a + * socket, and additionally obtain the endpoint of the remote peer. The + * function call always returns immediately. + * + * @param peer The socket into which the new connection will be accepted. + * Ownership of the peer object is retained by the caller, which must + * guarantee that it is valid until the handler is called. + * + * @param peer_endpoint An endpoint object into which the endpoint of the + * remote peer will be written. Ownership of the peer_endpoint object is + * retained by the caller, which must guarantee that it is valid until the + * handler is called. + * + * @param handler The handler to be called when the accept operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error // Result of operation. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, + void (boost::system::error_code)) + async_accept(basic_socket& peer, + endpoint_type& peer_endpoint, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a AcceptHandler. + BOOST_ASIO_ACCEPT_HANDLER_CHECK(AcceptHandler, handler) type_check; + + return this->get_service().async_accept(this->get_implementation(), peer, + &peer_endpoint, BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); + } +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BASIC_SOCKET_ACCEPTOR_EXT_HPP diff --git a/implementation/helper/boost/asio/basic_stream_socket_ext.hpp b/implementation/helper/boost/asio/basic_stream_socket_ext.hpp new file mode 100644 index 0000000..ab55eda --- /dev/null +++ b/implementation/helper/boost/asio/basic_stream_socket_ext.hpp @@ -0,0 +1,855 @@ +// +// basic_stream_socket_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP +#define BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { + +/// Provides stream-oriented socket functionality. +/** + * The basic_stream_socket_ext class template provides asynchronous and blocking + * stream-oriented socket functionality. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Unsafe. + * + * @par Concepts: + * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. + */ +template > +class basic_stream_socket_ext + : public basic_socket +{ +public: + /// (Deprecated: Use native_handle_type.) The native representation of a + /// socket. + typedef typename StreamSocketService::native_handle_type native_type; + + /// The native representation of a socket. + typedef typename StreamSocketService::native_handle_type native_handle_type; + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + /// Construct a basic_stream_socket_ext without opening it. + /** + * This constructor creates a stream socket without opening it. The socket + * needs to be opened and then connected or accepted before data can be sent + * or received on it. + * + * @param io_service The io_service object that the stream socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + */ + explicit basic_stream_socket_ext(boost::asio::io_service& io_service) + : basic_socket(io_service) + { + } + + /// Construct and open a basic_stream_socket_ext. + /** + * This constructor creates and opens a stream socket. The socket needs to be + * connected or accepted before data can be sent or received on it. + * + * @param io_service The io_service object that the stream socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_stream_socket_ext(boost::asio::io_service& io_service, + const protocol_type& protocol) + : basic_socket(io_service, protocol) + { + } + + /// Construct a basic_stream_socket_ext, opening it and binding it to the given + /// local endpoint. + /** + * This constructor creates a stream socket and automatically opens it bound + * to the specified endpoint on the local machine. The protocol used is the + * protocol associated with the given endpoint. + * + * @param io_service The io_service object that the stream socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param endpoint An endpoint on the local machine to which the stream + * socket will be bound. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_stream_socket_ext(boost::asio::io_service& io_service, + const endpoint_type& endpoint) + : basic_socket(io_service, endpoint) + { + } + + /// Construct a basic_stream_socket_ext on an existing native socket. + /** + * This constructor creates a stream socket object to hold an existing native + * socket. + * + * @param io_service The io_service object that the stream socket will use to + * dispatch handlers for any asynchronous operations performed on the socket. + * + * @param protocol An object specifying protocol parameters to be used. + * + * @param native_socket The new underlying socket implementation. + * + * @throws boost::system::system_error Thrown on failure. + */ + basic_stream_socket_ext(boost::asio::io_service& io_service, + const protocol_type& protocol, const native_handle_type& native_socket) + : basic_socket( + io_service, protocol, native_socket) + { + } + +#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a basic_stream_socket_ext from another. + /** + * This constructor moves a stream socket from one object to another. + * + * @param other The other basic_stream_socket_ext object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_stream_socket_ext(io_service&) constructor. + */ + basic_stream_socket_ext(basic_stream_socket_ext&& other) + : basic_socket( + BOOST_ASIO_MOVE_CAST(basic_stream_socket_ext)(other)) + { + } + + /// Move-assign a basic_stream_socket_ext from another. + /** + * This assignment operator moves a stream socket from one object to another. + * + * @param other The other basic_stream_socket_ext object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_stream_socket_ext(io_service&) constructor. + */ + basic_stream_socket_ext& operator=(basic_stream_socket_ext&& other) + { + basic_socket::operator=( + BOOST_ASIO_MOVE_CAST(basic_stream_socket_ext)(other)); + return *this; + } + + /// Move-construct a basic_stream_socket_ext from a socket of another protocol + /// type. + /** + * This constructor moves a stream socket from one object to another. + * + * @param other The other basic_stream_socket_ext object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_stream_socket_ext(io_service&) constructor. + */ + template + basic_stream_socket_ext( + basic_stream_socket_ext&& other, + typename enable_if::value>::type* = 0) + : basic_socket( + BOOST_ASIO_MOVE_CAST2(basic_stream_socket_ext< + Protocol1, StreamSocketService1>)(other)) + { + } + + /// Move-assign a basic_stream_socket_ext from a socket of another protocol type. + /** + * This assignment operator moves a stream socket from one object to another. + * + * @param other The other basic_stream_socket_ext object from which the move + * will occur. + * + * @note Following the move, the moved-from object is in the same state as if + * constructed using the @c basic_stream_socket_ext(io_service&) constructor. + */ + template + typename enable_if::value, + basic_stream_socket_ext>::type& operator=( + basic_stream_socket_ext&& other) + { + basic_socket::operator=( + BOOST_ASIO_MOVE_CAST2(basic_stream_socket_ext< + Protocol1, StreamSocketService1>)(other)); + return *this; + } +#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Send some data on the socket. + /** + * This function is used to send data on the stream socket. The function + * call will block until one or more bytes of the data has been sent + * successfully, or an until error occurs. + * + * @param buffers One or more data buffers to be sent on the socket. + * + * @returns The number of bytes sent. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref write function if you need to ensure that all data + * is written before the blocking operation completes. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.send(boost::asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send(const ConstBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = this->get_service().send( + this->get_implementation(), buffers, 0, ec); + boost::asio::detail::throw_error(ec, "send"); + return s; + } + + /// Send some data on the socket. + /** + * This function is used to send data on the stream socket. The function + * call will block until one or more bytes of the data has been sent + * successfully, or an until error occurs. + * + * @param buffers One or more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @returns The number of bytes sent. + * + * @throws boost::system::system_error Thrown on failure. + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref write function if you need to ensure that all data + * is written before the blocking operation completes. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.send(boost::asio::buffer(data, size), 0); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags) + { + boost::system::error_code ec; + std::size_t s = this->get_service().send( + this->get_implementation(), buffers, flags, ec); + boost::asio::detail::throw_error(ec, "send"); + return s; + } + + /// Send some data on the socket. + /** + * This function is used to send data on the stream socket. The function + * call will block until one or more bytes of the data has been sent + * successfully, or an until error occurs. + * + * @param buffers One or more data buffers to be sent on the socket. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes sent. Returns 0 if an error occurred. + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref write function if you need to ensure that all data + * is written before the blocking operation completes. + */ + template + std::size_t send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return this->get_service().send( + this->get_implementation(), buffers, flags, ec); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send data on the stream socket. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_send(boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (boost::system::error_code, std::size_t)) + async_send(const ConstBufferSequence& buffers, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + return this->get_service().async_send( + this->get_implementation(), buffers, 0, + BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Start an asynchronous send. + /** + * This function is used to asynchronously send data on the stream socket. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be sent on the socket. Although + * the buffers object may be copied as necessary, ownership of the underlying + * memory blocks is retained by the caller, which must guarantee that they + * remain valid until the handler is called. + * + * @param flags Flags specifying how the send call is to be made. + * + * @param handler The handler to be called when the send operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes sent. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The send operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To send a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_send(boost::asio::buffer(data, size), 0, handler); + * @endcode + * See the @ref buffer documentation for information on sending multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (boost::system::error_code, std::size_t)) + async_send(const ConstBufferSequence& buffers, + socket_base::message_flags flags, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + return this->get_service().async_send( + this->get_implementation(), buffers, flags, + BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Receive some data on the socket. + /** + * This function is used to receive data on the stream socket. The function + * call will block until one or more bytes of data has been received + * successfully, or until an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @returns The number of bytes received. + * + * @throws boost::system::system_error Thrown on failure. An error code of + * boost::asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.receive(boost::asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive(const MutableBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, 0, ec); + boost::asio::detail::throw_error(ec, "receive"); + return s; + } + + /// Receive some data on the socket. + /** + * This function is used to receive data on the stream socket. The function + * call will block until one or more bytes of data has been received + * successfully, or until an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @returns The number of bytes received. + * + * @throws boost::system::system_error Thrown on failure. An error code of + * boost::asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.receive(boost::asio::buffer(data, size), 0); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags) + { + boost::system::error_code ec; + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, flags, ec); + boost::asio::detail::throw_error(ec, "receive"); + return s; + } + + /// Receive some data on a connected socket. + /** + * This function is used to receive data on the stream socket. The function + * call will block until one or more bytes of data has been received + * successfully, or until an error occurs. + * + * @param buffers One or more buffers into which the data will be received. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes received. Returns 0 if an error occurred. + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that the + * requested amount of data is read before the blocking operation completes. + */ + template + std::size_t receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return this->get_service().receive( + this->get_implementation(), buffers, flags, ec); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive data from the stream + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref async_read function if you need to ensure + * that the requested amount of data is received before the asynchronous + * operation completes. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.async_receive(boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) + async_receive(const MutableBufferSequence& buffers, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; + + return this->get_service().async_receive(this->get_implementation(), + buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + } + + /// Start an asynchronous receive. + /** + * This function is used to asynchronously receive data from the stream + * socket. The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be received. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param flags Flags specifying how the receive call is to be made. + * + * @param handler The handler to be called when the receive operation + * completes. Copies will be made of the handler as required. The function + * signature of the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes received. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The receive operation may not receive all of the requested number of + * bytes. Consider using the @ref async_read function if you need to ensure + * that the requested amount of data is received before the asynchronous + * operation completes. + * + * @par Example + * To receive into a single data buffer use the @ref buffer function as + * follows: + * @code + * socket.async_receive(boost::asio::buffer(data, size), 0, handler); + * @endcode + * See the @ref buffer documentation for information on receiving into + * multiple buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) + async_receive(const MutableBufferSequence& buffers, + socket_base::message_flags flags, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; + + return this->get_service().async_receive(this->get_implementation(), + buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + } + + /// Write some data to the socket. + /** + * This function is used to write data to the stream socket. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the socket. + * + * @returns The number of bytes written. + * + * @throws boost::system::system_error Thrown on failure. An error code of + * boost::asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * socket.write_some(boost::asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = this->get_service().send( + this->get_implementation(), buffers, 0, ec); + boost::asio::detail::throw_error(ec, "write_some"); + return s; + } + + /// Write some data to the socket. + /** + * This function is used to write data to the stream socket. The function call + * will block until one or more bytes of the data has been written + * successfully, or until an error occurs. + * + * @param buffers One or more data buffers to be written to the socket. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes written. Returns 0 if an error occurred. + * + * @note The write_some operation may not transmit all of the data to the + * peer. Consider using the @ref write function if you need to ensure that + * all data is written before the blocking operation completes. + */ + template + std::size_t write_some(const ConstBufferSequence& buffers, + boost::system::error_code& ec) + { + return this->get_service().send(this->get_implementation(), buffers, 0, ec); + } + + /// Start an asynchronous write. + /** + * This function is used to asynchronously write data to the stream socket. + * The function call always returns immediately. + * + * @param buffers One or more data buffers to be written to the socket. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the write operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes written. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The write operation may not transmit all of the data to the peer. + * Consider using the @ref async_write function if you need to ensure that all + * data is written before the asynchronous operation completes. + * + * @par Example + * To write a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_write_some(boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on writing multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (boost::system::error_code, std::size_t)) + async_write_some(const ConstBufferSequence& buffers, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a WriteHandler. + BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; + + return this->get_service().async_send(this->get_implementation(), + buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + } + + /// Read some data from the socket. + /** + * This function is used to read data from the stream socket. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @returns The number of bytes read. + * + * @throws boost::system::system_error Thrown on failure. An error code of + * boost::asio::error::eof indicates that the connection was closed by the + * peer. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * socket.read_some(boost::asio::buffer(data, size)); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers) + { + boost::system::error_code ec; + std::size_t s = this->get_service().receive( + this->get_implementation(), buffers, 0, ec); + boost::asio::detail::throw_error(ec, "read_some"); + return s; + } + + /// Read some data from the socket. + /** + * This function is used to read data from the stream socket. The function + * call will block until one or more bytes of data has been read successfully, + * or until an error occurs. + * + * @param buffers One or more buffers into which the data will be read. + * + * @param ec Set to indicate what error occurred, if any. + * + * @returns The number of bytes read. Returns 0 if an error occurred. + * + * @note The read_some operation may not read all of the requested number of + * bytes. Consider using the @ref read function if you need to ensure that + * the requested amount of data is read before the blocking operation + * completes. + */ + template + std::size_t read_some(const MutableBufferSequence& buffers, + boost::system::error_code& ec) + { + return this->get_service().receive( + this->get_implementation(), buffers, 0, ec); + } + + /// Start an asynchronous read. + /** + * This function is used to asynchronously read data from the stream socket. + * The function call always returns immediately. + * + * @param buffers One or more buffers into which the data will be read. + * Although the buffers object may be copied as necessary, ownership of the + * underlying memory blocks is retained by the caller, which must guarantee + * that they remain valid until the handler is called. + * + * @param handler The handler to be called when the read operation completes. + * Copies will be made of the handler as required. The function signature of + * the handler must be: + * @code void handler( + * const boost::system::error_code& error, // Result of operation. + * std::size_t bytes_transferred // Number of bytes read. + * ); @endcode + * Regardless of whether the asynchronous operation completes immediately or + * not, the handler will not be invoked from within this function. Invocation + * of the handler will be performed in a manner equivalent to using + * boost::asio::io_service::post(). + * + * @note The read operation may not read all of the requested number of bytes. + * Consider using the @ref async_read function if you need to ensure that the + * requested amount of data is read before the asynchronous operation + * completes. + * + * @par Example + * To read into a single data buffer use the @ref buffer function as follows: + * @code + * socket.async_read_some(boost::asio::buffer(data, size), handler); + * @endcode + * See the @ref buffer documentation for information on reading into multiple + * buffers in one go, and how to use it with arrays, boost::array or + * std::vector. + */ + template + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) + async_read_some(const MutableBufferSequence& buffers, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) + { + // If you get an error on the following line it means that your handler does + // not meet the documented type requirements for a ReadHandler. + BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL(ReadHandler, handler) type_check; + + return this->get_service().async_receive(this->get_implementation(), + buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + } +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_EXT_HPP diff --git a/implementation/helper/boost/asio/datagram_socket_service_ext.hpp b/implementation/helper/boost/asio/datagram_socket_service_ext.hpp new file mode 100644 index 0000000..7648581 --- /dev/null +++ b/implementation/helper/boost/asio/datagram_socket_service_ext.hpp @@ -0,0 +1,437 @@ +// +// datagram_socket_service_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_EXT_ASIO_DATAGRAM_SOCKET_SERVICE_EXT_HPP +#define BOOST_EXT_ASIO_DATAGRAM_SOCKET_SERVICE_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) +# include +#elif defined(BOOST_ASIO_HAS_IOCP) +# include "detail/win_iocp_socket_service_ext.hpp" +#else +# include "detail/reactive_socket_service_ext.hpp" +#endif + +#include + +namespace boost { +namespace asio { + +/// Default service implementation for a datagram socket. +template +class datagram_socket_service_ext +#if defined(GENERATING_DOCUMENTATION) + : public boost::asio::io_service::service +#else + : public boost::asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static boost::asio::io_service::id id; +#endif + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + +private: + // The type of the platform-specific implementation. +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + typedef detail::null_socket_service service_impl_type; +#elif defined(BOOST_ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service_ext service_impl_type; +#else + typedef detail::reactive_socket_service_ext service_impl_type; +#endif + +public: + /// The type of a datagram socket. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// (Deprecated: Use native_handle_type.) The native socket type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef typename service_impl_type::native_handle_type native_type; +#endif + + /// The native socket type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef typename service_impl_type::native_handle_type native_handle_type; +#endif + + /// Construct a new datagram socket service for the specified io_service. + explicit datagram_socket_service_ext(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + datagram_socket_service_ext >(io_service), + service_impl_(io_service) + { + } + + /// Construct a new datagram socket implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new datagram socket implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another datagram socket implementation. + void move_assign(implementation_type& impl, + datagram_socket_service_ext& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } + + /// Move-construct a new datagram socket implementation from another protocol + /// type. + template + void converting_move_construct(implementation_type& impl, + typename datagram_socket_service_ext< + Protocol1>::implementation_type& other_impl, + typename enable_if::value>::type* = 0) + { + service_impl_.template converting_move_construct( + impl, other_impl); + } +#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a datagram socket implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + // Open a new datagram socket implementation. + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) + { + if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_DGRAM)) + service_impl_.open(impl, protocol, ec); + else + ec = boost::asio::error::invalid_argument; + return ec; + } + + /// Assign an existing native socket to a datagram socket. + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_handle_type& native_socket, + boost::system::error_code& ec) + { + return service_impl_.assign(impl, protocol, native_socket, ec); + } + + /// Determine whether the socket is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a datagram socket implementation. + boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// (Deprecated: Use native_handle().) Get the native socket implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Get the native socket implementation. + native_handle_type native_handle(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Cancel all asynchronous operations associated with the socket. + boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Determine whether the socket is at the out-of-band data mark. + bool at_mark(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.at_mark(impl, ec); + } + + /// Determine the number of bytes available for reading. + std::size_t available(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.available(impl, ec); + } + + // Bind the datagram socket to the specified local endpoint. + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) + { + return service_impl_.bind(impl, endpoint, ec); + } + + /// Connect the datagram socket to the specified endpoint. + boost::system::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, boost::system::error_code& ec) + { + return service_impl_.connect(impl, peer_endpoint, ec); + } + + /// Start an asynchronous connect. + template + BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, + void (boost::system::error_code)) + async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, + BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) + { + detail::async_result_init< + ConnectHandler, void (boost::system::error_code)> init( + BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); + + service_impl_.async_connect(impl, peer_endpoint, init.handler); + + return init.result.get(); + } + + /// Set a socket option. + template + boost::system::error_code set_option(implementation_type& impl, + const SettableSocketOption& option, boost::system::error_code& ec) + { + return service_impl_.set_option(impl, option, ec); + } + + /// Get a socket option. + template + boost::system::error_code get_option(const implementation_type& impl, + GettableSocketOption& option, boost::system::error_code& ec) const + { + return service_impl_.get_option(impl, option, ec); + } + + /// Perform an IO control command on the socket. + template + boost::system::error_code io_control(implementation_type& impl, + IoControlCommand& command, boost::system::error_code& ec) + { + return service_impl_.io_control(impl, command, ec); + } + + /// Gets the non-blocking mode of the socket. + bool non_blocking(const implementation_type& impl) const + { + return service_impl_.non_blocking(impl); + } + + /// Sets the non-blocking mode of the socket. + boost::system::error_code non_blocking(implementation_type& impl, + bool mode, boost::system::error_code& ec) + { + return service_impl_.non_blocking(impl, mode, ec); + } + + /// Gets the non-blocking mode of the native socket implementation. + bool native_non_blocking(const implementation_type& impl) const + { + return service_impl_.native_non_blocking(impl); + } + + /// Sets the non-blocking mode of the native socket implementation. + boost::system::error_code native_non_blocking(implementation_type& impl, + bool mode, boost::system::error_code& ec) + { + return service_impl_.native_non_blocking(impl, mode, ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.remote_endpoint(impl, ec); + } + + /// Disable sends or receives on the socket. + boost::system::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) + { + return service_impl_.shutdown(impl, what, ec); + } + + /// Send the given data to the peer. + template + std::size_t send(implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return service_impl_.send(impl, buffers, flags, ec); + } + + /// Start an asynchronous send. + template + BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (boost::system::error_code, std::size_t)) + async_send(implementation_type& impl, const ConstBufferSequence& buffers, + socket_base::message_flags flags, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) + { + detail::async_result_init< + WriteHandler, void (boost::system::error_code, std::size_t)> init( + BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + + service_impl_.async_send(impl, buffers, flags, init.handler); + + return init.result.get(); + } + + /// Send a datagram to the specified endpoint. + template + std::size_t send_to(implementation_type& impl, + const ConstBufferSequence& buffers, const endpoint_type& destination, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return service_impl_.send_to(impl, buffers, destination, flags, ec); + } + + /// Start an asynchronous send. + template + BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (boost::system::error_code, std::size_t)) + async_send_to(implementation_type& impl, + const ConstBufferSequence& buffers, const endpoint_type& destination, + socket_base::message_flags flags, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) + { + detail::async_result_init< + WriteHandler, void (boost::system::error_code, std::size_t)> init( + BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + + service_impl_.async_send_to(impl, buffers, + destination, flags, init.handler); + + return init.result.get(); + } + + /// Receive some data from the peer. + template + std::size_t receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return service_impl_.receive(impl, buffers, flags, ec); + } + + /// Start an asynchronous receive. + template + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (boost::system::error_code, std::size_t)) + async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) + { + detail::async_result_init< + ReadHandler, void (boost::system::error_code, std::size_t)> init( + BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + + service_impl_.async_receive(impl, buffers, flags, init.handler); + + return init.result.get(); + } + + /// Receive a datagram with the endpoint of the sender. + template + std::size_t receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return service_impl_.receive_from(impl, buffers, sender_endpoint, flags, + ec); + } + + /// Start an asynchronous receive that will get the endpoint of the sender. + template + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (boost::system::error_code, std::size_t, boost::asio::ip::address)) + async_receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) + { + detail::async_result_init< + ReadHandler, void (boost::system::error_code, std::size_t)> init( + BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + + service_impl_.async_receive_from(impl, buffers, + sender_endpoint, flags, init.handler); + + return init.result.get(); + } + +private: + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + service_impl_.shutdown_service(); + } + + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DATAGRAM_SOCKET_SERVICE_HPP diff --git a/implementation/helper/boost/asio/detail/handler_type_requirements_ext.hpp b/implementation/helper/boost/asio/detail/handler_type_requirements_ext.hpp new file mode 100644 index 0000000..34b0375 --- /dev/null +++ b/implementation/helper/boost/asio/detail/handler_type_requirements_ext.hpp @@ -0,0 +1,520 @@ +// +// detail/handler_type_requirements_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP +#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +// Older versions of gcc have difficulty compiling the sizeof expressions where +// we test the handler type requirements. We'll disable checking of handler type +// requirements for those compilers, but otherwise enable it by default. +#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) +# if !defined(__GNUC__) || (__GNUC__ >= 4) +# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 +# endif // !defined(__GNUC__) || (__GNUC__ >= 4) +#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) + +// With C++0x we can use a combination of enhanced SFINAE and static_assert to +// generate better template error messages. As this technique is not yet widely +// portable, we'll only enable it for tested compilers. +#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(BOOST_ASIO_MSVC) +# if (_MSC_VER >= 1600) +# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 +# endif // (_MSC_VER >= 1600) +# endif // defined(BOOST_ASIO_MSVC) +# if defined(__clang__) +# if __has_feature(__cxx_static_assert__) +# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 +# endif // __has_feature(cxx_static_assert) +# endif // defined(__clang__) +#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) + +#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) +# include +#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) + +// Newer gcc, clang need special treatment to suppress unused typedef warnings. +#if defined(__clang__) +# if defined(__apple_build_version__) +# if (__clang_major__ >= 7) +# if !defined(BOOST_ASIO_UNUSED_TYPEDEF) +# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) +# endif +# endif // (__clang_major__ >= 7) +# elif ((__clang_major__ == 3) && (__clang_minor__ >= 6)) \ + || (__clang_major__ > 3) +# if !defined(BOOST_ASIO_UNUSED_TYPEDEF) +# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) +# endif +# endif // ((__clang_major__ == 3) && (__clang_minor__ >= 6)) + // || (__clang_major__ > 3) +#elif defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) +# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) +#endif // defined(__GNUC__) +#if !defined(BOOST_ASIO_UNUSED_TYPEDEF) +# define BOOST_ASIO_UNUSED_TYPEDEF +#endif // !defined(BOOST_ASIO_UNUSED_TYPEDEF) + +namespace boost { +namespace asio { +namespace detail { + +#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) + +# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) + +template +auto zero_arg_handler_test(Handler h, void*) + -> decltype( + sizeof(Handler(static_cast(h))), + ((h)()), + char(0)); + +template +char (&zero_arg_handler_test(Handler, ...))[2]; + +template +auto one_arg_handler_test(Handler h, Arg1* a1) + -> decltype( + sizeof(Handler(static_cast(h))), + ((h)(*a1)), + char(0)); + +template +char (&one_arg_handler_test(Handler h, ...))[2]; + +template +auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) + -> decltype( + sizeof(Handler(static_cast(h))), + ((h)(*a1, *a2)), + char(0)); + +template +char (&two_arg_handler_test(Handler, ...))[2]; + +template +auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) + -> decltype( + sizeof(Handler(static_cast(h))), + ((h)(*a1, *a2, *a3)), + char(0)); + +template +char (&three_arg_handler_test(Handler, ...))[2]; + +# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ + static_assert(expr, msg); + +# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) + +# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) + +# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) + +template T& lvref(); +template T& lvref(T); +template const T& clvref(); +template const T& clvref(T); +template char argbyv(T); + +#if 0 +template +struct handler_type_requirements +{ +}; +#endif + +#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void()) asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::zero_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), 0)) == 1, \ + "CompletionHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()(), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_READ_HANDLER_CHECK_EXT( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code, std::size_t, \ + boost::asio::ip::address)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::three_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "ReadHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + + +#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code, std::size_t)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::two_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "WriteHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::one_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "AcceptHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::one_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "ConnectHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \ + handler_type, handler, iter_type) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code, iter_type)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::two_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "ComposedConnectHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ + handler_type, handler, iter_type) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code, iter_type)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::two_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "ResolveHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::one_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "WaitHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code, int)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::two_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "SignalHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::one_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "HandshakeHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code, std::size_t)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::two_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "BufferedHandshakeHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::one_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "ShutdownHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) + +#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_READ_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \ + handler_type, handler, iter_type) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ + handler_type, handler, iter_type) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/handler_type_requirements_ext_local.hpp b/implementation/helper/boost/asio/detail/handler_type_requirements_ext_local.hpp new file mode 100644 index 0000000..717eb6e --- /dev/null +++ b/implementation/helper/boost/asio/detail/handler_type_requirements_ext_local.hpp @@ -0,0 +1,536 @@ +// +// detail/handler_type_requirements_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP +#define BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +// Older versions of gcc have difficulty compiling the sizeof expressions where +// we test the handler type requirements. We'll disable checking of handler type +// requirements for those compilers, but otherwise enable it by default. +#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) +# if !defined(__GNUC__) || (__GNUC__ >= 4) +# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS 1 +# endif // !defined(__GNUC__) || (__GNUC__ >= 4) +#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) + +// With C++0x we can use a combination of enhanced SFINAE and static_assert to +// generate better template error messages. As this technique is not yet widely +// portable, we'll only enable it for tested compilers. +#if !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) +# if defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) +# if defined(__GXX_EXPERIMENTAL_CXX0X__) +# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 +# endif // defined(__GXX_EXPERIMENTAL_CXX0X__) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4) +# endif // defined(__GNUC__) +# if defined(BOOST_ASIO_MSVC) +# if (_MSC_VER >= 1600) +# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 +# endif // (_MSC_VER >= 1600) +# endif // defined(BOOST_ASIO_MSVC) +# if defined(__clang__) +# if __has_feature(__cxx_static_assert__) +# define BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT 1 +# endif // __has_feature(cxx_static_assert) +# endif // defined(__clang__) +#endif // !defined(BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS) + +#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) +# include +#endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) + +// Newer gcc, clang need special treatment to suppress unused typedef warnings. +#if defined(__clang__) +# if defined(__apple_build_version__) +# if (__clang_major__ >= 7) +# if !defined(BOOST_ASIO_UNUSED_TYPEDEF) +# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) +# endif +# endif // (__clang_major__ >= 7) +# elif ((__clang_major__ == 3) && (__clang_minor__ >= 6)) \ + || (__clang_major__ > 3) +# if !defined(BOOST_ASIO_UNUSED_TYPEDEF) +# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) +# endif +# endif // ((__clang_major__ == 3) && (__clang_minor__ >= 6)) + // || (__clang_major__ > 3) +#elif defined(__GNUC__) +# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) +# define BOOST_ASIO_UNUSED_TYPEDEF __attribute__((__unused__)) +# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ > 4) +#endif // defined(__GNUC__) +#if !defined(BOOST_ASIO_UNUSED_TYPEDEF) +# define BOOST_ASIO_UNUSED_TYPEDEF +#endif // !defined(BOOST_ASIO_UNUSED_TYPEDEF) + +namespace boost { +namespace asio { +namespace detail { + +#if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) + +# if defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) + +template +auto zero_arg_handler_test(Handler h, void*) + -> decltype( + sizeof(Handler(static_cast(h))), + ((h)()), + char(0)); + +template +char (&zero_arg_handler_test(Handler, ...))[2]; + +template +auto one_arg_handler_test(Handler h, Arg1* a1) + -> decltype( + sizeof(Handler(static_cast(h))), + ((h)(*a1)), + char(0)); + +template +char (&one_arg_handler_test(Handler h, ...))[2]; + +template +auto two_arg_handler_test(Handler h, Arg1* a1, Arg2* a2) + -> decltype( + sizeof(Handler(static_cast(h))), + ((h)(*a1, *a2)), + char(0)); + +template +char (&two_arg_handler_test(Handler, ...))[2]; + +template +auto three_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3) + -> decltype( + sizeof(Handler(static_cast(h))), + ((h)(*a1, *a2, *a3)), + char(0)); + +template +char (&three_arg_handler_test(Handler, ...))[2]; + +# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ + static_assert(expr, msg); + +template +auto four_arg_handler_test(Handler h, Arg1* a1, Arg2* a2, Arg3* a3, Arg4* a4) + -> decltype( + sizeof(Handler(static_cast(h))), + ((h)(*a1, *a2, *a3, *a4)), + char(0)); + +template +char (&four_arg_handler_test(Handler, ...))[2]; + +# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) \ + static_assert(expr, msg); + + +# else // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) + +# define BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT(expr, msg) + +# endif // defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS_ASSERT) + +template T& lvref(); +template T& lvref(T); +template const T& clvref(); +template const T& clvref(T); +template char argbyv(T); + +#if 0 +template +struct handler_type_requirements +{ +}; +#endif + +#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void()) asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::zero_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), 0)) == 1, \ + "CompletionHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()(), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_READ_HANDLER_CHECK_EXT_LOCAL( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code, std::size_t, \ + std::uint32_t, \ + std::uint32_t)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::four_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "ReadHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code, std::size_t)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::two_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "WriteHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::one_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "AcceptHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::one_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "ConnectHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \ + handler_type, handler, iter_type) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code, iter_type)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::two_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "ComposedConnectHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ + handler_type, handler, iter_type) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code, iter_type)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::two_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "ResolveHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::one_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "WaitHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code, int)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::two_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "SignalHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::one_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "HandshakeHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code, std::size_t)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::two_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0), \ + static_cast(0))) == 1, \ + "BufferedHandshakeHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref(), \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ + handler_type, handler) \ + \ + typedef BOOST_ASIO_HANDLER_TYPE(handler_type, \ + void(boost::system::error_code)) \ + asio_true_handler_type; \ + \ + BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \ + sizeof(boost::asio::detail::one_arg_handler_test( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>(), \ + static_cast(0))) == 1, \ + "ShutdownHandler type requirements not met") \ + \ + typedef boost::asio::detail::handler_type_requirements< \ + sizeof( \ + boost::asio::detail::argbyv( \ + boost::asio::detail::clvref< \ + asio_true_handler_type>())) + \ + sizeof( \ + boost::asio::detail::lvref< \ + asio_true_handler_type>()( \ + boost::asio::detail::lvref()), \ + char(0))> BOOST_ASIO_UNUSED_TYPEDEF + +#else // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) + +#define BOOST_ASIO_COMPLETION_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_READ_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_WRITE_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_ACCEPT_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_CONNECT_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_COMPOSED_CONNECT_HANDLER_CHECK( \ + handler_type, handler, iter_type) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_RESOLVE_HANDLER_CHECK( \ + handler_type, handler, iter_type) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_WAIT_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_SIGNAL_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_HANDSHAKE_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_BUFFERED_HANDSHAKE_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#define BOOST_ASIO_SHUTDOWN_HANDLER_CHECK( \ + handler_type, handler) \ + typedef int BOOST_ASIO_UNUSED_TYPEDEF + +#endif // !defined(BOOST_ASIO_ENABLE_HANDLER_TYPE_REQUIREMENTS) + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // BOOST_ASIO_DETAIL_HANDLER_TYPE_REQUIREMENTS_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp b/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp new file mode 100644 index 0000000..3b4a4a8 --- /dev/null +++ b/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext.ipp @@ -0,0 +1,270 @@ +// +// detail/reactive_socket_service_base_ext.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP +#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#if !defined(BOOST_ASIO_HAS_IOCP) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +reactive_socket_service_base_ext::reactive_socket_service_base_ext( + boost::asio::io_service& io_service) + : reactor_(use_service(io_service)) +{ + reactor_.init_task(); +} + +void reactive_socket_service_base_ext::shutdown_service() +{ +} + +void reactive_socket_service_base_ext::construct( + reactive_socket_service_base_ext::base_implementation_type& impl) +{ + impl.socket_ = invalid_socket; + impl.state_ = 0; +} + +void reactive_socket_service_base_ext::base_move_construct( + reactive_socket_service_base_ext::base_implementation_type& impl, + reactive_socket_service_base_ext::base_implementation_type& other_impl) +{ + impl.socket_ = other_impl.socket_; + other_impl.socket_ = invalid_socket; + + impl.state_ = other_impl.state_; + other_impl.state_ = 0; + + reactor_.move_descriptor(impl.socket_, + impl.reactor_data_, other_impl.reactor_data_); +} + +void reactive_socket_service_base_ext::base_move_assign( + reactive_socket_service_base_ext::base_implementation_type& impl, + reactive_socket_service_base_ext& other_service, + reactive_socket_service_base_ext::base_implementation_type& other_impl) +{ + destroy(impl); + + impl.socket_ = other_impl.socket_; + other_impl.socket_ = invalid_socket; + + impl.state_ = other_impl.state_; + other_impl.state_ = 0; + + other_service.reactor_.move_descriptor(impl.socket_, + impl.reactor_data_, other_impl.reactor_data_); +} + +void reactive_socket_service_base_ext::destroy( + reactive_socket_service_base_ext::base_implementation_type& impl) +{ + if (impl.socket_ != invalid_socket) + { + BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "close")); + + reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, + (impl.state_ & socket_ops::possible_dup) == 0); + + boost::system::error_code ignored_ec; + socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); + } +} + +boost::system::error_code reactive_socket_service_base_ext::close( + reactive_socket_service_base_ext::base_implementation_type& impl, + boost::system::error_code& ec) +{ + if (is_open(impl)) + { + BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "close")); + + reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, + (impl.state_ & socket_ops::possible_dup) == 0); + } + + socket_ops::close(impl.socket_, impl.state_, false, ec); + + // The descriptor is closed by the OS even if close() returns an error. + // + // (Actually, POSIX says the state of the descriptor is unspecified. On + // Linux the descriptor is apparently closed anyway; e.g. see + // http://lkml.org/lkml/2005/9/10/129 + // We'll just have to assume that other OSes follow the same behaviour. The + // known exception is when Windows's closesocket() function fails with + // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). + construct(impl); + + return ec; +} + +boost::system::error_code reactive_socket_service_base_ext::cancel( + reactive_socket_service_base_ext::base_implementation_type& impl, + boost::system::error_code& ec) +{ + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "cancel")); + + reactor_.cancel_ops(impl.socket_, impl.reactor_data_); + ec = boost::system::error_code(); + return ec; +} + +boost::system::error_code reactive_socket_service_base_ext::do_open( + reactive_socket_service_base_ext::base_implementation_type& impl, + int af, int type, int protocol, boost::system::error_code& ec) +{ + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + socket_holder sock(socket_ops::socket(af, type, protocol, ec)); + if (sock.get() == invalid_socket) + return ec; + + if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) + { + ec = boost::system::error_code(err, + boost::asio::error::get_system_category()); + return ec; + } + + impl.socket_ = sock.release(); + switch (type) + { + case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; + case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; + default: impl.state_ = 0; break; + } + ec = boost::system::error_code(); + return ec; +} + +boost::system::error_code reactive_socket_service_base_ext::do_assign( + reactive_socket_service_base_ext::base_implementation_type& impl, int type, + const reactive_socket_service_base_ext::native_handle_type& native_socket, + boost::system::error_code& ec) +{ + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + if (int err = reactor_.register_descriptor( + native_socket, impl.reactor_data_)) + { + ec = boost::system::error_code(err, + boost::asio::error::get_system_category()); + return ec; + } + + impl.socket_ = native_socket; + switch (type) + { + case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; + case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; + default: impl.state_ = 0; break; + } + impl.state_ |= socket_ops::possible_dup; + ec = boost::system::error_code(); + return ec; +} + +void reactive_socket_service_base_ext::start_op( + reactive_socket_service_base_ext::base_implementation_type& impl, + int op_type, reactor_op* op, bool is_continuation, + bool is_non_blocking, bool noop) +{ + if (!noop) + { + if ((impl.state_ & socket_ops::non_blocking) + || socket_ops::set_internal_non_blocking( + impl.socket_, impl.state_, true, op->ec_)) + { + reactor_.start_op(op_type, impl.socket_, + impl.reactor_data_, op, is_continuation, is_non_blocking); + return; + } + } + + reactor_.post_immediate_completion(op, is_continuation); +} + +void reactive_socket_service_base_ext::start_accept_op( + reactive_socket_service_base_ext::base_implementation_type& impl, + reactor_op* op, bool is_continuation, bool peer_is_open) +{ + if (!peer_is_open) + start_op(impl, reactor::read_op, op, true, is_continuation, false); + else + { + op->ec_ = boost::asio::error::already_open; + reactor_.post_immediate_completion(op, is_continuation); + } +} + +void reactive_socket_service_base_ext::start_connect_op( + reactive_socket_service_base_ext::base_implementation_type& impl, + reactor_op* op, bool is_continuation, + const socket_addr_type* addr, size_t addrlen) +{ + if ((impl.state_ & socket_ops::non_blocking) + || socket_ops::set_internal_non_blocking( + impl.socket_, impl.state_, true, op->ec_)) + { + if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) + { + if (op->ec_ == boost::asio::error::in_progress + || op->ec_ == boost::asio::error::would_block) + { + op->ec_ = boost::system::error_code(); + reactor_.start_op(reactor::connect_op, impl.socket_, + impl.reactor_data_, op, is_continuation, false); + return; + } + } + } + + reactor_.post_immediate_completion(op, is_continuation); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // !defined(BOOST_ASIO_HAS_IOCP) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_IPP diff --git a/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp b/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp new file mode 100644 index 0000000..26521cf --- /dev/null +++ b/implementation/helper/boost/asio/detail/impl/reactive_socket_service_base_ext_local.ipp @@ -0,0 +1,270 @@ +// +// detail/reactive_socket_service_base_ext_local.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP +#define BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#if !defined(BOOST_ASIO_HAS_IOCP) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +reactive_socket_service_base_ext_local::reactive_socket_service_base_ext_local( + boost::asio::io_service& io_service) + : reactor_(use_service(io_service)) +{ + reactor_.init_task(); +} + +void reactive_socket_service_base_ext_local::shutdown_service() +{ +} + +void reactive_socket_service_base_ext_local::construct( + reactive_socket_service_base_ext_local::base_implementation_type& impl) +{ + impl.socket_ = invalid_socket; + impl.state_ = 0; +} + +void reactive_socket_service_base_ext_local::base_move_construct( + reactive_socket_service_base_ext_local::base_implementation_type& impl, + reactive_socket_service_base_ext_local::base_implementation_type& other_impl) +{ + impl.socket_ = other_impl.socket_; + other_impl.socket_ = invalid_socket; + + impl.state_ = other_impl.state_; + other_impl.state_ = 0; + + reactor_.move_descriptor(impl.socket_, + impl.reactor_data_, other_impl.reactor_data_); +} + +void reactive_socket_service_base_ext_local::base_move_assign( + reactive_socket_service_base_ext_local::base_implementation_type& impl, + reactive_socket_service_base_ext_local& other_service, + reactive_socket_service_base_ext_local::base_implementation_type& other_impl) +{ + destroy(impl); + + impl.socket_ = other_impl.socket_; + other_impl.socket_ = invalid_socket; + + impl.state_ = other_impl.state_; + other_impl.state_ = 0; + + other_service.reactor_.move_descriptor(impl.socket_, + impl.reactor_data_, other_impl.reactor_data_); +} + +void reactive_socket_service_base_ext_local::destroy( + reactive_socket_service_base_ext_local::base_implementation_type& impl) +{ + if (impl.socket_ != invalid_socket) + { + BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "close")); + + reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, + (impl.state_ & socket_ops::possible_dup) == 0); + + boost::system::error_code ignored_ec; + socket_ops::close(impl.socket_, impl.state_, true, ignored_ec); + } +} + +boost::system::error_code reactive_socket_service_base_ext_local::close( + reactive_socket_service_base_ext_local::base_implementation_type& impl, + boost::system::error_code& ec) +{ + if (is_open(impl)) + { + BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "close")); + + reactor_.deregister_descriptor(impl.socket_, impl.reactor_data_, + (impl.state_ & socket_ops::possible_dup) == 0); + } + + socket_ops::close(impl.socket_, impl.state_, false, ec); + + // The descriptor is closed by the OS even if close() returns an error. + // + // (Actually, POSIX says the state of the descriptor is unspecified. On + // Linux the descriptor is apparently closed anyway; e.g. see + // http://lkml.org/lkml/2005/9/10/129 + // We'll just have to assume that other OSes follow the same behaviour. The + // known exception is when Windows's closesocket() function fails with + // WSAEWOULDBLOCK, but this case is handled inside socket_ops::close(). + construct(impl); + + return ec; +} + +boost::system::error_code reactive_socket_service_base_ext_local::cancel( + reactive_socket_service_base_ext_local::base_implementation_type& impl, + boost::system::error_code& ec) +{ + if (!is_open(impl)) + { + ec = boost::asio::error::bad_descriptor; + return ec; + } + + BOOST_ASIO_HANDLER_OPERATION(("socket", &impl, "cancel")); + + reactor_.cancel_ops(impl.socket_, impl.reactor_data_); + ec = boost::system::error_code(); + return ec; +} + +boost::system::error_code reactive_socket_service_base_ext_local::do_open( + reactive_socket_service_base_ext_local::base_implementation_type& impl, + int af, int type, int protocol, boost::system::error_code& ec) +{ + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + socket_holder sock(socket_ops::socket(af, type, protocol, ec)); + if (sock.get() == invalid_socket) + return ec; + + if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_)) + { + ec = boost::system::error_code(err, + boost::asio::error::get_system_category()); + return ec; + } + + impl.socket_ = sock.release(); + switch (type) + { + case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; + case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; + default: impl.state_ = 0; break; + } + ec = boost::system::error_code(); + return ec; +} + +boost::system::error_code reactive_socket_service_base_ext_local::do_assign( + reactive_socket_service_base_ext_local::base_implementation_type& impl, int type, + const reactive_socket_service_base_ext_local::native_handle_type& native_socket, + boost::system::error_code& ec) +{ + if (is_open(impl)) + { + ec = boost::asio::error::already_open; + return ec; + } + + if (int err = reactor_.register_descriptor( + native_socket, impl.reactor_data_)) + { + ec = boost::system::error_code(err, + boost::asio::error::get_system_category()); + return ec; + } + + impl.socket_ = native_socket; + switch (type) + { + case SOCK_STREAM: impl.state_ = socket_ops::stream_oriented; break; + case SOCK_DGRAM: impl.state_ = socket_ops::datagram_oriented; break; + default: impl.state_ = 0; break; + } + impl.state_ |= socket_ops::possible_dup; + ec = boost::system::error_code(); + return ec; +} + +void reactive_socket_service_base_ext_local::start_op( + reactive_socket_service_base_ext_local::base_implementation_type& impl, + int op_type, reactor_op* op, bool is_continuation, + bool is_non_blocking, bool noop) +{ + if (!noop) + { + if ((impl.state_ & socket_ops::non_blocking) + || socket_ops::set_internal_non_blocking( + impl.socket_, impl.state_, true, op->ec_)) + { + reactor_.start_op(op_type, impl.socket_, + impl.reactor_data_, op, is_continuation, is_non_blocking); + return; + } + } + + reactor_.post_immediate_completion(op, is_continuation); +} + +void reactive_socket_service_base_ext_local::start_accept_op( + reactive_socket_service_base_ext_local::base_implementation_type& impl, + reactor_op* op, bool is_continuation, bool peer_is_open) +{ + if (!peer_is_open) + start_op(impl, reactor::read_op, op, true, is_continuation, false); + else + { + op->ec_ = boost::asio::error::already_open; + reactor_.post_immediate_completion(op, is_continuation); + } +} + +void reactive_socket_service_base_ext_local::start_connect_op( + reactive_socket_service_base_ext_local::base_implementation_type& impl, + reactor_op* op, bool is_continuation, + const socket_addr_type* addr, size_t addrlen) +{ + if ((impl.state_ & socket_ops::non_blocking) + || socket_ops::set_internal_non_blocking( + impl.socket_, impl.state_, true, op->ec_)) + { + if (socket_ops::connect(impl.socket_, addr, addrlen, op->ec_) != 0) + { + if (op->ec_ == boost::asio::error::in_progress + || op->ec_ == boost::asio::error::would_block) + { + op->ec_ = boost::system::error_code(); + reactor_.start_op(reactor::connect_op, impl.socket_, + impl.reactor_data_, op, is_continuation, false); + return; + } + } + } + + reactor_.post_immediate_completion(op, is_continuation); +} + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // !defined(BOOST_ASIO_HAS_IOCP) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#endif // BOOST_ASIO_DETAIL_IMPL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_IPP diff --git a/implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp b/implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp new file mode 100644 index 0000000..fe90e83 --- /dev/null +++ b/implementation/helper/boost/asio/detail/impl/socket_ops_ext.ipp @@ -0,0 +1,210 @@ +// +// detail/impl/socket_ops_ext.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP +#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP + +#include + +#include + +namespace boost { +namespace asio { +namespace detail { +namespace socket_ops { + +signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, + int flags, socket_addr_type* addr, std::size_t* addrlen, + boost::system::error_code& ec, boost::asio::ip::address& da) +{ + clear_last_error(); +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) + GUID WSARecvMsg_GUID = WSAID_WSARECVMSG; + LPFN_WSARECVMSG WSARecvMsg; + DWORD NumberOfBytes; + + error_wrapper(WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, + &WSARecvMsg_GUID, sizeof WSARecvMsg_GUID, + &WSARecvMsg, sizeof WSARecvMsg, + &NumberOfBytes, NULL, NULL), ec); + if (ec.value() == SOCKET_ERROR) { + WSARecvMsg = NULL; + return 0; + } + + WSABUF wsaBuf; + WSAMSG msg; + char controlBuffer[1024]; + msg.name = addr; + msg.namelen = *addrlen; + wsaBuf.buf = bufs->buf; + wsaBuf.len = bufs->len; + msg.lpBuffers = &wsaBuf; + msg.dwBufferCount = count; + msg.Control.len = sizeof controlBuffer; + msg.Control.buf = controlBuffer; + msg.dwFlags = flags; + + DWORD dwNumberOfBytesRecvd; + signed_size_type result = error_wrapper(WSARecvMsg(s, &msg, &dwNumberOfBytesRecvd, NULL, NULL), ec); + + if (result >= 0) { + ec = boost::system::error_code(); + + // Find destination address + for (LPWSACMSGHDR cmsg = WSA_CMSG_FIRSTHDR(&msg); + cmsg != NULL; + cmsg = WSA_CMSG_NXTHDR(&msg, cmsg)) + { + if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO) + continue; + + struct in_pktinfo *pi = (struct in_pktinfo *) WSA_CMSG_DATA(cmsg); + if (pi) + { + da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); + } + } + } else { + dwNumberOfBytesRecvd = -1; + } + return dwNumberOfBytesRecvd; +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) + char cmbuf[0x100]; + msghdr msg = msghdr(); + init_msghdr_msg_name(msg.msg_name, addr); + msg.msg_namelen = static_cast(*addrlen); + msg.msg_iov = bufs; + msg.msg_iovlen = static_cast(count); + msg.msg_control = cmbuf; + msg.msg_controllen = sizeof(cmbuf); + signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); + *addrlen = msg.msg_namelen; + if (result >= 0) { + ec = boost::system::error_code(); + + // Find destination address + for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) + { + if (cmsg->cmsg_level != IPPROTO_IP || cmsg->cmsg_type != IP_PKTINFO) + continue; + + struct in_pktinfo *pi = (struct in_pktinfo *) CMSG_DATA(cmsg); + if (pi) + { + da = boost::asio::ip::address_v4(ntohl(pi->ipi_addr.s_addr)); + } + } + } + return result; +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) +} + +size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, + size_t count, int flags, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // Read some data. + for (;;) + { + // Try to complete the operation without blocking. + signed_size_type bytes = socket_ops::recvfrom( + s, bufs, count, flags, addr, addrlen, ec, da); + + // Check if operation succeeded. + if (bytes >= 0) + return bytes; + + // Operation failed. + if ((state & user_set_non_blocking) + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_read(s, 0, ec) < 0) + return 0; + } +} + +#if defined(BOOST_ASIO_HAS_IOCP) + +void complete_iocp_recvfrom( + const weak_cancel_token_type& cancel_token, + boost::system::error_code& ec, boost::asio::ip::address& da) +{ + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_NETNAME_DELETED) + { + if (cancel_token.expired()) + ec = boost::asio::error::operation_aborted; + else + ec = boost::asio::error::connection_reset; + } + else if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = boost::asio::error::connection_refused; + } +} + +#else // defined(BOOST_ASIO_HAS_IOCP) + +bool non_blocking_recvfrom(socket_type s, + buf* bufs, size_t count, int flags, + socket_addr_type* addr, std::size_t* addrlen, + boost::system::error_code& ec, size_t& bytes_transferred, boost::asio::ip::address& da) +{ + for (;;) + { + // Read some data. + signed_size_type bytes = socket_ops::recvfrom( + s, bufs, count, flags, addr, addrlen, ec, da); + + // Retry operation if interrupted by signal. + if (ec == boost::asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + + // Operation is complete. + if (bytes >= 0) + { + ec = boost::system::error_code(); + bytes_transferred = bytes; + } + else + bytes_transferred = 0; + + return true; + } +} + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +} // namespace socket_ops +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_IPP diff --git a/implementation/helper/boost/asio/detail/impl/socket_ops_ext_local.ipp b/implementation/helper/boost/asio/detail/impl/socket_ops_ext_local.ipp new file mode 100644 index 0000000..b601e11 --- /dev/null +++ b/implementation/helper/boost/asio/detail/impl/socket_ops_ext_local.ipp @@ -0,0 +1,302 @@ +// +// detail/impl/socket_ops_ext_local.ipp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP +#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP + +#include + +#include + +namespace boost { +namespace asio { +namespace detail { +namespace socket_ops { + +signed_size_type recv(socket_type s, buf* bufs, size_t count, + int flags, boost::system::error_code& ec, + std::uint32_t& uid, std::uint32_t& gid) +{ + uid = 0xFFFFFFFF; + gid = 0xFFFFFFFF; + struct ucred *ucredp; + clear_last_error(); +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) + // Receive some data. + DWORD recv_buf_count = static_cast(count); + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int result = error_wrapper(::WSARecv(s, bufs, + recv_buf_count, &bytes_transferred, &recv_flags, 0, 0), ec); + if (ec.value() == ERROR_NETNAME_DELETED) + ec = boost::asio::error::connection_reset; + else if (ec.value() == ERROR_PORT_UNREACHABLE) + ec = boost::asio::error::connection_refused; + if (result != 0) + return socket_error_retval; + ec = boost::system::error_code(); + return bytes_transferred; +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + msg.msg_iov = bufs; + msg.msg_iovlen = static_cast(count); + + union { + struct cmsghdr cmh; + char control[CMSG_SPACE(sizeof(struct ucred))]; + } control_un; + + // Set 'control_un' to describe ancillary data that we want to receive + control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); + control_un.cmh.cmsg_level = SOL_SOCKET; + control_un.cmh.cmsg_type = SCM_CREDENTIALS; + + // Set 'msg' fields to describe 'control_un' + msg.msg_control = control_un.control; + msg.msg_controllen = sizeof(control_un.control); + + signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); + if (result >= 0) { + ec = boost::system::error_code(); + + // Find UID / GID + for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) + { + if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS + || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) + continue; + + ucredp = (struct ucred *) CMSG_DATA(cmsg); + if (ucredp) { + uid = ucredp->uid; + gid = ucredp->gid; + } + } + } + return result; +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) +} + +signed_size_type recvfrom(socket_type s, buf* bufs, size_t count, + int flags, socket_addr_type* addr, std::size_t* addrlen, + boost::system::error_code& ec, + std::uint32_t& uid, std::uint32_t& gid) +{ + uid = 0xFFFFFFFF; + gid = 0xFFFFFFFF; + struct ucred *ucredp; + clear_last_error(); +#if defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) + // Receive some data. + DWORD recv_buf_count = static_cast(count); + DWORD bytes_transferred = 0; + DWORD recv_flags = flags; + int tmp_addrlen = (int)*addrlen; + int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count, + &bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec); + *addrlen = (std::size_t)tmp_addrlen; + if (ec.value() == ERROR_NETNAME_DELETED) + ec = boost::asio::error::connection_reset; + else if (ec.value() == ERROR_PORT_UNREACHABLE) + ec = boost::asio::error::connection_refused; + if (result != 0) + return socket_error_retval; + ec = boost::system::error_code(); + return bytes_transferred; +#else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) + msghdr msg = msghdr(); + init_msghdr_msg_name(msg.msg_name, addr); + msg.msg_namelen = static_cast(*addrlen); + msg.msg_iov = bufs; + msg.msg_iovlen = static_cast(count); + + union { + struct cmsghdr cmh; + char control[CMSG_SPACE(sizeof(struct ucred))]; + } control_un; + + // Set 'control_un' to describe ancillary data that we want to receive + control_un.cmh.cmsg_len = CMSG_LEN(sizeof(struct ucred)); + control_un.cmh.cmsg_level = SOL_SOCKET; + control_un.cmh.cmsg_type = SCM_CREDENTIALS; + + // Set 'msg' fields to describe 'control_un' + msg.msg_control = control_un.control; + msg.msg_controllen = sizeof(control_un.control); + + signed_size_type result = error_wrapper(::recvmsg(s, &msg, flags), ec); + *addrlen = msg.msg_namelen; + if (result >= 0) { + ec = boost::system::error_code(); + // Find UID / GID + for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); + cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) + { + if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_CREDENTIALS + || cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred))) + continue; + + ucredp = (struct ucred *) CMSG_DATA(cmsg); + if (ucredp) { + uid = ucredp->uid; + gid = ucredp->gid; + } + } + } + return result; +#endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) +} + +size_t sync_recvfrom(socket_type s, state_type state, buf* bufs, + size_t count, int flags, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec, + std::uint32_t& uid, std::uint32_t& gid) +{ + if (s == invalid_socket) + { + ec = boost::asio::error::bad_descriptor; + return 0; + } + + // Read some data. + for (;;) + { + // Try to complete the operation without blocking. + signed_size_type bytes = socket_ops::recvfrom( + s, bufs, count, flags, addr, addrlen, ec, uid, gid); + + // Check if operation succeeded. + if (bytes >= 0) + return bytes; + + // Operation failed. + if ((state & user_set_non_blocking) + || (ec != boost::asio::error::would_block + && ec != boost::asio::error::try_again)) + return 0; + + // Wait for socket to become ready. + if (socket_ops::poll_read(s, 0, ec) < 0) + return 0; + } +} + +#if defined(BOOST_ASIO_HAS_IOCP) + +void complete_iocp_recvfrom( + const weak_cancel_token_type& cancel_token, + boost::system::error_code& ec, + std::uint32_t& uid, std::uint32_t& gid) +{ + uid = 0xFFFFFFFF; + gid = 0xFFFFFFFF; + // Map non-portable errors to their portable counterparts. + if (ec.value() == ERROR_NETNAME_DELETED) + { + if (cancel_token.expired()) + ec = boost::asio::error::operation_aborted; + else + ec = boost::asio::error::connection_reset; + } + else if (ec.value() == ERROR_PORT_UNREACHABLE) + { + ec = boost::asio::error::connection_refused; + } +} + +#else // defined(BOOST_ASIO_HAS_IOCP) + +bool non_blocking_recv(socket_type s, + buf* bufs, size_t count, int flags, bool is_stream, + boost::system::error_code& ec, size_t& bytes_transferred, + std::uint32_t& uid, std::uint32_t& gid) +{ + for (;;) + { + // Read some data. + signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec, uid, gid); + + // Check for end of stream. + if (is_stream && bytes == 0) + { + ec = boost::asio::error::eof; + return true; + } + + // Retry operation if interrupted by signal. + if (ec == boost::asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + + // Operation is complete. + if (bytes >= 0) + { + ec = boost::system::error_code(); + bytes_transferred = bytes; + } + else + bytes_transferred = 0; + + return true; + } +} + +bool non_blocking_recvfrom(socket_type s, + buf* bufs, size_t count, int flags, + socket_addr_type* addr, std::size_t* addrlen, + boost::system::error_code& ec, size_t& bytes_transferred, + std::uint32_t& uid, std::uint32_t& gid) +{ + for (;;) + { + // Read some data. + signed_size_type bytes = socket_ops::recvfrom( + s, bufs, count, flags, addr, addrlen, ec, uid, gid); + + // Retry operation if interrupted by signal. + if (ec == boost::asio::error::interrupted) + continue; + + // Check if we need to run the operation again. + if (ec == boost::asio::error::would_block + || ec == boost::asio::error::try_again) + return false; + + // Operation is complete. + if (bytes >= 0) + { + ec = boost::system::error_code(); + bytes_transferred = bytes; + } + else + bytes_transferred = 0; + + return true; + } +} + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +} // namespace socket_ops +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_IPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext.hpp new file mode 100644 index 0000000..531ad21 --- /dev/null +++ b/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext.hpp @@ -0,0 +1,126 @@ +// +// detail/reactive_socket_recv_op_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class reactive_socket_recv_op_base_ext : public reactor_op_ext +{ +public: + reactive_socket_recv_op_base_ext(socket_type socket, + socket_ops::state_type state, const MutableBufferSequence& buffers, + socket_base::message_flags flags, func_type complete_func) + : reactor_op_ext(&reactive_socket_recv_op_base_ext::do_perform, complete_func), + socket_(socket), + state_(state), + buffers_(buffers), + flags_(flags) + { + } + + static bool do_perform(reactor_op* base) + { + reactive_socket_recv_op_base_ext* o( + static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + return socket_ops::non_blocking_recv(o->socket_, + bufs.buffers(), bufs.count(), o->flags_, + (o->state_ & socket_ops::stream_oriented) != 0, + o->ec_, o->bytes_transferred_); + } + +private: + socket_type socket_; + socket_ops::state_type state_; + MutableBufferSequence buffers_; + socket_base::message_flags flags_; +}; + +template +class reactive_socket_recv_op_ext : + public reactive_socket_recv_op_base_ext +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext); + + reactive_socket_recv_op_ext(socket_type socket, + socket_ops::state_type state, const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler& handler) + : reactive_socket_recv_op_base_ext(socket, state, + buffers, flags, &reactive_socket_recv_op_ext::do_complete), + handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + const boost::system::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_recv_op_ext* o(static_cast(base)); + ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; + + BOOST_ASIO_HANDLER_COMPLETION((o)); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder3 + handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); + p.h = boost::asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + BOOST_ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp new file mode 100644 index 0000000..6c151ca --- /dev/null +++ b/implementation/helper/boost/asio/detail/reactive_socket_recv_op_ext_local.hpp @@ -0,0 +1,126 @@ +// +// detail/reactive_socket_recv_op_ext_local.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class reactive_socket_recv_op_base_ext_local : public reactor_op_ext_local +{ +public: + reactive_socket_recv_op_base_ext_local(socket_type socket, + socket_ops::state_type state, const MutableBufferSequence& buffers, + socket_base::message_flags flags, func_type complete_func) + : reactor_op_ext_local(&reactive_socket_recv_op_base_ext_local::do_perform, complete_func), + socket_(socket), + state_(state), + buffers_(buffers), + flags_(flags) + { + } + + static bool do_perform(reactor_op* base) + { + reactive_socket_recv_op_base_ext_local* o( + static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + return socket_ops::non_blocking_recv(o->socket_, + bufs.buffers(), bufs.count(), o->flags_, + (o->state_ & socket_ops::stream_oriented) != 0, + o->ec_, o->bytes_transferred_, o->uid_, o->gid_); + } + +private: + socket_type socket_; + socket_ops::state_type state_; + MutableBufferSequence buffers_; + socket_base::message_flags flags_; +}; + +template +class reactive_socket_recv_op_ext_local : + public reactive_socket_recv_op_base_ext_local +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recv_op_ext_local); + + reactive_socket_recv_op_ext_local(socket_type socket, + socket_ops::state_type state, const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler& handler) + : reactive_socket_recv_op_base_ext_local(socket, state, + buffers, flags, &reactive_socket_recv_op_ext_local::do_complete), + handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + const boost::system::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_recv_op_ext_local* o(static_cast(base)); + ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; + + BOOST_ASIO_HANDLER_COMPLETION((o)); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder4 + handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); + p.h = boost::asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + BOOST_ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECV_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp new file mode 100644 index 0000000..93bdf01 --- /dev/null +++ b/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext.hpp @@ -0,0 +1,136 @@ +// +// detail/reactive_socket_recvfrom_op_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class reactive_socket_recvfrom_op_base_ext : public reactor_op_ext +{ +public: + reactive_socket_recvfrom_op_base_ext(socket_type socket, int protocol_type, + const MutableBufferSequence& buffers, Endpoint& endpoint, + socket_base::message_flags flags, func_type complete_func) + : reactor_op_ext(&reactive_socket_recvfrom_op_base_ext::do_perform, complete_func), + socket_(socket), + protocol_type_(protocol_type), + buffers_(buffers), + sender_endpoint_(endpoint), + flags_(flags) + { + } + + static bool do_perform(reactor_op* base) + { + reactive_socket_recvfrom_op_base_ext* o( + static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + std::size_t addr_len = o->sender_endpoint_.capacity(); + bool result = socket_ops::non_blocking_recvfrom(o->socket_, + bufs.buffers(), bufs.count(), o->flags_, + o->sender_endpoint_.data(), &addr_len, + o->ec_, o->bytes_transferred_, o->da_); + + if (result && !o->ec_) + o->sender_endpoint_.resize(addr_len); + + return result; + } + +private: + socket_type socket_; + int protocol_type_; + MutableBufferSequence buffers_; + Endpoint& sender_endpoint_; + socket_base::message_flags flags_; +}; + +template +class reactive_socket_recvfrom_op_ext : + public reactive_socket_recvfrom_op_base_ext +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext); + + reactive_socket_recvfrom_op_ext(socket_type socket, int protocol_type, + const MutableBufferSequence& buffers, Endpoint& endpoint, + socket_base::message_flags flags, Handler& handler) + : reactive_socket_recvfrom_op_base_ext( + socket, protocol_type, buffers, endpoint, flags, + &reactive_socket_recvfrom_op_ext::do_complete), + handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + const boost::system::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_recvfrom_op_ext* o( + static_cast(base)); + ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; + + BOOST_ASIO_HANDLER_COMPLETION((o)); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder3 + handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); + p.h = boost::asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + BOOST_ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp new file mode 100644 index 0000000..a38844d --- /dev/null +++ b/implementation/helper/boost/asio/detail/reactive_socket_recvfrom_op_ext_local.hpp @@ -0,0 +1,136 @@ +// +// detail/reactive_socket_recvfrom_op_ext_local.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class reactive_socket_recvfrom_op_base_ext_local : public reactor_op_ext_local +{ +public: + reactive_socket_recvfrom_op_base_ext_local(socket_type socket, int protocol_type, + const MutableBufferSequence& buffers, Endpoint& endpoint, + socket_base::message_flags flags, func_type complete_func) + : reactor_op_ext_local(&reactive_socket_recvfrom_op_base_ext_local::do_perform, complete_func), + socket_(socket), + protocol_type_(protocol_type), + buffers_(buffers), + sender_endpoint_(endpoint), + flags_(flags) + { + } + + static bool do_perform(reactor_op* base) + { + reactive_socket_recvfrom_op_base_ext_local* o( + static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + std::size_t addr_len = o->sender_endpoint_.capacity(); + bool result = socket_ops::non_blocking_recvfrom(o->socket_, + bufs.buffers(), bufs.count(), o->flags_, + o->sender_endpoint_.data(), &addr_len, + o->ec_, o->bytes_transferred_, o->uid_, o->gid_); + + if (result && !o->ec_) + o->sender_endpoint_.resize(addr_len); + + return result; + } + +private: + socket_type socket_; + int protocol_type_; + MutableBufferSequence buffers_; + Endpoint& sender_endpoint_; + socket_base::message_flags flags_; +}; + +template +class reactive_socket_recvfrom_op_ext_local : + public reactive_socket_recvfrom_op_base_ext_local +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvfrom_op_ext_local); + + reactive_socket_recvfrom_op_ext_local(socket_type socket, int protocol_type, + const MutableBufferSequence& buffers, Endpoint& endpoint, + socket_base::message_flags flags, Handler& handler) + : reactive_socket_recvfrom_op_base_ext_local( + socket, protocol_type, buffers, endpoint, flags, + &reactive_socket_recvfrom_op_ext_local::do_complete), + handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + const boost::system::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_recvfrom_op_ext_local* o( + static_cast(base)); + ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; + + BOOST_ASIO_HANDLER_COMPLETION((o)); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder4 + handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); + p.h = boost::asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + BOOST_ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVFROM_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp new file mode 100644 index 0000000..b28572b --- /dev/null +++ b/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext.hpp @@ -0,0 +1,128 @@ +// +// detail/reactive_socket_recvmsg_op_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class reactive_socket_recvmsg_op_base_ext : public reactor_op_ext +{ +public: + reactive_socket_recvmsg_op_base_ext(socket_type socket, + const MutableBufferSequence& buffers, socket_base::message_flags in_flags, + socket_base::message_flags& out_flags, func_type complete_func) + : reactor_op_ext(&reactive_socket_recvmsg_op_base_ext::do_perform, complete_func), + socket_(socket), + buffers_(buffers), + in_flags_(in_flags), + out_flags_(out_flags) + { + } + + static bool do_perform(reactor_op* base) + { + reactive_socket_recvmsg_op_base_ext* o( + static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + return socket_ops::non_blocking_recvmsg(o->socket_, + bufs.buffers(), bufs.count(), + o->in_flags_, o->out_flags_, + o->ec_, o->bytes_transferred_); + } + +private: + socket_type socket_; + MutableBufferSequence buffers_; + socket_base::message_flags in_flags_; + socket_base::message_flags& out_flags_; +}; + +template +class reactive_socket_recvmsg_op_ext : + public reactive_socket_recvmsg_op_base_ext +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext); + + reactive_socket_recvmsg_op_ext(socket_type socket, + const MutableBufferSequence& buffers, socket_base::message_flags in_flags, + socket_base::message_flags& out_flags, Handler& handler) + : reactive_socket_recvmsg_op_base_ext(socket, buffers, + in_flags, out_flags, &reactive_socket_recvmsg_op_ext::do_complete), + handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + const boost::system::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_recvmsg_op_ext* o( + static_cast(base)); + ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; + + BOOST_ASIO_HANDLER_COMPLETION((o)); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder3 + handler(o->handler_, o->ec_, o->bytes_transferred_, o->da_); + p.h = boost::asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_)); + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + BOOST_ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp new file mode 100644 index 0000000..7b5bc53 --- /dev/null +++ b/implementation/helper/boost/asio/detail/reactive_socket_recvmsg_op_ext_local.hpp @@ -0,0 +1,128 @@ +// +// detail/reactive_socket_recvmsg_op_ext_local.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class reactive_socket_recvmsg_op_base_ext_local : public reactor_op_ext_local +{ +public: + reactive_socket_recvmsg_op_base_ext_local(socket_type socket, + const MutableBufferSequence& buffers, socket_base::message_flags in_flags, + socket_base::message_flags& out_flags, func_type complete_func) + : reactor_op_ext_local(&reactive_socket_recvmsg_op_base_ext_local::do_perform, complete_func), + socket_(socket), + buffers_(buffers), + in_flags_(in_flags), + out_flags_(out_flags) + { + } + + static bool do_perform(reactor_op* base) + { + reactive_socket_recvmsg_op_base_ext_local* o( + static_cast(base)); + + buffer_sequence_adapter bufs(o->buffers_); + + return socket_ops::non_blocking_recvmsg(o->socket_, + bufs.buffers(), bufs.count(), + o->in_flags_, o->out_flags_, + o->ec_, o->bytes_transferred_); + } + +private: + socket_type socket_; + MutableBufferSequence buffers_; + socket_base::message_flags in_flags_; + socket_base::message_flags& out_flags_; +}; + +template +class reactive_socket_recvmsg_op_ext_local : + public reactive_socket_recvmsg_op_base_ext_local +{ +public: + BOOST_ASIO_DEFINE_HANDLER_PTR(reactive_socket_recvmsg_op_ext_local); + + reactive_socket_recvmsg_op_ext_local(socket_type socket, + const MutableBufferSequence& buffers, socket_base::message_flags in_flags, + socket_base::message_flags& out_flags, Handler& handler) + : reactive_socket_recvmsg_op_base_ext_local(socket, buffers, + in_flags, out_flags, &reactive_socket_recvmsg_op_ext_local::do_complete), + handler_(BOOST_ASIO_MOVE_CAST(Handler)(handler)) + { + } + + static void do_complete(io_service_impl* owner, operation* base, + const boost::system::error_code& /*ec*/, + std::size_t /*bytes_transferred*/) + { + // Take ownership of the handler object. + reactive_socket_recvmsg_op_ext_local* o( + static_cast(base)); + ptr p = { boost::asio::detail::addressof(o->handler_), o, o }; + + BOOST_ASIO_HANDLER_COMPLETION((o)); + + // Make a copy of the handler so that the memory can be deallocated before + // the upcall is made. Even if we're not about to make an upcall, a + // sub-object of the handler may be the true owner of the memory associated + // with the handler. Consequently, a local copy of the handler is required + // to ensure that any owning sub-object remains valid until after we have + // deallocated the memory here. + detail::binder4 + handler(o->handler_, o->ec_, o->bytes_transferred_, o->uid_, o->gid_); + p.h = boost::asio::detail::addressof(handler.handler_); + p.reset(); + + // Make the upcall if required. + if (owner) + { + fenced_block b(fenced_block::half); + BOOST_ASIO_HANDLER_INVOCATION_BEGIN((handler.arg1_, handler.arg2_, handler.arg3_, handler.arg4_)); + boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_); + BOOST_ASIO_HANDLER_INVOCATION_END; + } + } + +private: + Handler handler_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_RECVMSG_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext.hpp new file mode 100644 index 0000000..3c0107c --- /dev/null +++ b/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext.hpp @@ -0,0 +1,455 @@ +// +// detail/reactive_socket_service_base_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +#if !defined(BOOST_ASIO_HAS_IOCP) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +class reactive_socket_service_base_ext +{ +public: + // The native type of a socket. + typedef socket_type native_handle_type; + + // The implementation type of the socket. + struct base_implementation_type + { + // The native socket representation. + socket_type socket_; + + // The current state of the socket. + socket_ops::state_type state_; + + // Per-descriptor data used by the reactor. + reactor::per_descriptor_data reactor_data_; + }; + + // Constructor. + BOOST_ASIO_DECL reactive_socket_service_base_ext( + boost::asio::io_service& io_service); + + // Destroy all user-defined handler objects owned by the service. + BOOST_ASIO_DECL void shutdown_service(); + + // Construct a new socket implementation. + BOOST_ASIO_DECL void construct(base_implementation_type& impl); + + // Move-construct a new socket implementation. + BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, + base_implementation_type& other_impl); + + // Move-assign from another socket implementation. + BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, + reactive_socket_service_base_ext& other_service, + base_implementation_type& other_impl); + + // Destroy a socket implementation. + BOOST_ASIO_DECL void destroy(base_implementation_type& impl); + + // Determine whether the socket is open. + bool is_open(const base_implementation_type& impl) const + { + return impl.socket_ != invalid_socket; + } + + // Destroy a socket implementation. + BOOST_ASIO_DECL boost::system::error_code close( + base_implementation_type& impl, boost::system::error_code& ec); + + // Get the native socket representation. + native_handle_type native_handle(base_implementation_type& impl) + { + return impl.socket_; + } + + // Cancel all operations associated with the socket. + BOOST_ASIO_DECL boost::system::error_code cancel( + base_implementation_type& impl, boost::system::error_code& ec); + + // Determine whether the socket is at the out-of-band data mark. + bool at_mark(const base_implementation_type& impl, + boost::system::error_code& ec) const + { + return socket_ops::sockatmark(impl.socket_, ec); + } + + // Determine the number of bytes available for reading. + std::size_t available(const base_implementation_type& impl, + boost::system::error_code& ec) const + { + return socket_ops::available(impl.socket_, ec); + } + + // Place the socket into the state where it will listen for new connections. + boost::system::error_code listen(base_implementation_type& impl, + int backlog, boost::system::error_code& ec) + { + socket_ops::listen(impl.socket_, backlog, ec); + return ec; + } + + // Perform an IO control command on the socket. + template + boost::system::error_code io_control(base_implementation_type& impl, + IO_Control_Command& command, boost::system::error_code& ec) + { + socket_ops::ioctl(impl.socket_, impl.state_, command.name(), + static_cast(command.data()), ec); + return ec; + } + + // Gets the non-blocking mode of the socket. + bool non_blocking(const base_implementation_type& impl) const + { + return (impl.state_ & socket_ops::user_set_non_blocking) != 0; + } + + // Sets the non-blocking mode of the socket. + boost::system::error_code non_blocking(base_implementation_type& impl, + bool mode, boost::system::error_code& ec) + { + socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); + return ec; + } + + // Gets the non-blocking mode of the native socket implementation. + bool native_non_blocking(const base_implementation_type& impl) const + { + return (impl.state_ & socket_ops::internal_non_blocking) != 0; + } + + // Sets the non-blocking mode of the native socket implementation. + boost::system::error_code native_non_blocking(base_implementation_type& impl, + bool mode, boost::system::error_code& ec) + { + socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); + return ec; + } + + // Disable sends or receives on the socket. + boost::system::error_code shutdown(base_implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) + { + socket_ops::shutdown(impl.socket_, what, ec); + return ec; + } + + // Send the given data to the peer. + template + size_t send(base_implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + buffer_sequence_adapter bufs(buffers); + + return socket_ops::sync_send(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); + } + + // Wait until data can be sent without blocking. + size_t send(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags, boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_write(impl.socket_, impl.state_, ec); + + return 0; + } + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_send(base_implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_send_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, buffers, flags, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send")); + + start_op(impl, reactor::write_op, p.p, is_continuation, true, + ((impl.state_ & socket_ops::stream_oriented) + && buffer_sequence_adapter::all_empty(buffers))); + p.v = p.p = 0; + } + + // Start an asynchronous wait until data can be sent without blocking. + template + void async_send(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_null_buffers_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", + &impl, "async_send(null_buffers)")); + + start_op(impl, reactor::write_op, p.p, is_continuation, false, false); + p.v = p.p = 0; + } + + // Receive some data from the peer. Returns the number of bytes received. + template + size_t receive(base_implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + buffer_sequence_adapter bufs(buffers); + + return socket_ops::sync_recv(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); + } + + // Wait until data can be received without blocking. + size_t receive(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags, boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_read(impl.socket_, impl.state_, ec); + + return 0; + } + + // Start an asynchronous receive. The buffer for the data being received + // must be valid for the lifetime of the asynchronous operation. + template + void async_receive(base_implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_recv_op_ext op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_receive")); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, is_continuation, + (flags & socket_base::message_out_of_band) == 0, + ((impl.state_ & socket_ops::stream_oriented) + && buffer_sequence_adapter::all_empty(buffers))); + p.v = p.p = 0; + } + + // Wait until data can be received without blocking. + template + void async_receive(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_null_buffers_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", + &impl, "async_receive(null_buffers)")); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, is_continuation, false, false); + p.v = p.p = 0; + } + + // Receive some data with associated flags. Returns the number of bytes + // received. + template + size_t receive_with_flags(base_implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags in_flags, + socket_base::message_flags& out_flags, boost::system::error_code& ec) + { + buffer_sequence_adapter bufs(buffers); + + return socket_ops::sync_recvmsg(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), in_flags, out_flags, ec); + } + + // Wait until data can be received without blocking. + size_t receive_with_flags(base_implementation_type& impl, + const null_buffers&, socket_base::message_flags, + socket_base::message_flags& out_flags, boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_read(impl.socket_, impl.state_, ec); + + // Clear out_flags, since we cannot give it any other sensible value when + // performing a null_buffers operation. + out_flags = 0; + + return 0; + } + + // Start an asynchronous receive. The buffer for the data being received + // must be valid for the lifetime of the asynchronous operation. + template + void async_receive_with_flags(base_implementation_type& impl, + const MutableBufferSequence& buffers, socket_base::message_flags in_flags, + socket_base::message_flags& out_flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_recvmsg_op_ext op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", + &impl, "async_receive_with_flags")); + + start_op(impl, + (in_flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, is_continuation, + (in_flags & socket_base::message_out_of_band) == 0, false); + p.v = p.p = 0; + } + + // Wait until data can be received without blocking. + template + void async_receive_with_flags(base_implementation_type& impl, + const null_buffers&, socket_base::message_flags in_flags, + socket_base::message_flags& out_flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_null_buffers_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, + "async_receive_with_flags(null_buffers)")); + + // Clear out_flags, since we cannot give it any other sensible value when + // performing a null_buffers operation. + out_flags = 0; + + start_op(impl, + (in_flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, is_continuation, false, false); + p.v = p.p = 0; + } + +protected: + // Open a new socket implementation. + BOOST_ASIO_DECL boost::system::error_code do_open( + base_implementation_type& impl, int af, + int type, int protocol, boost::system::error_code& ec); + + // Assign a native socket to a socket implementation. + BOOST_ASIO_DECL boost::system::error_code do_assign( + base_implementation_type& impl, int type, + const native_handle_type& native_socket, boost::system::error_code& ec); + + // Start the asynchronous read or write operation. + BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, + reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); + + // Start the asynchronous accept operation. + BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, + reactor_op* op, bool is_continuation, bool peer_is_open); + + // Start the asynchronous connect operation. + BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, + reactor_op* op, bool is_continuation, + const socket_addr_type* addr, size_t addrlen); + + // The selector that performs event demultiplexing for the service. + reactor& reactor_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#if defined(BOOST_ASIO_HEADER_ONLY) +# include +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // !defined(BOOST_ASIO_HAS_IOCP) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext_local.hpp new file mode 100644 index 0000000..e97fca2 --- /dev/null +++ b/implementation/helper/boost/asio/detail/reactive_socket_service_base_ext_local.hpp @@ -0,0 +1,454 @@ +// +// detail/reactive_socket_service_base_ext_local.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +#if !defined(BOOST_ASIO_HAS_IOCP) \ + && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +class reactive_socket_service_base_ext_local +{ +public: + // The native type of a socket. + typedef socket_type native_handle_type; + + // The implementation type of the socket. + struct base_implementation_type + { + // The native socket representation. + socket_type socket_; + + // The current state of the socket. + socket_ops::state_type state_; + + // Per-descriptor data used by the reactor. + reactor::per_descriptor_data reactor_data_; + }; + + // Constructor. + BOOST_ASIO_DECL reactive_socket_service_base_ext_local( + boost::asio::io_service& io_service); + + // Destroy all user-defined handler objects owned by the service. + BOOST_ASIO_DECL void shutdown_service(); + + // Construct a new socket implementation. + BOOST_ASIO_DECL void construct(base_implementation_type& impl); + + // Move-construct a new socket implementation. + BOOST_ASIO_DECL void base_move_construct(base_implementation_type& impl, + base_implementation_type& other_impl); + + // Move-assign from another socket implementation. + BOOST_ASIO_DECL void base_move_assign(base_implementation_type& impl, + reactive_socket_service_base_ext_local& other_service, + base_implementation_type& other_impl); + + // Destroy a socket implementation. + BOOST_ASIO_DECL void destroy(base_implementation_type& impl); + + // Determine whether the socket is open. + bool is_open(const base_implementation_type& impl) const + { + return impl.socket_ != invalid_socket; + } + + // Destroy a socket implementation. + BOOST_ASIO_DECL boost::system::error_code close( + base_implementation_type& impl, boost::system::error_code& ec); + + // Get the native socket representation. + native_handle_type native_handle(base_implementation_type& impl) + { + return impl.socket_; + } + + // Cancel all operations associated with the socket. + BOOST_ASIO_DECL boost::system::error_code cancel( + base_implementation_type& impl, boost::system::error_code& ec); + + // Determine whether the socket is at the out-of-band data mark. + bool at_mark(const base_implementation_type& impl, + boost::system::error_code& ec) const + { + return socket_ops::sockatmark(impl.socket_, ec); + } + + // Determine the number of bytes available for reading. + std::size_t available(const base_implementation_type& impl, + boost::system::error_code& ec) const + { + return socket_ops::available(impl.socket_, ec); + } + + // Place the socket into the state where it will listen for new connections. + boost::system::error_code listen(base_implementation_type& impl, + int backlog, boost::system::error_code& ec) + { + socket_ops::listen(impl.socket_, backlog, ec); + return ec; + } + + // Perform an IO control command on the socket. + template + boost::system::error_code io_control(base_implementation_type& impl, + IO_Control_Command& command, boost::system::error_code& ec) + { + socket_ops::ioctl(impl.socket_, impl.state_, command.name(), + static_cast(command.data()), ec); + return ec; + } + + // Gets the non-blocking mode of the socket. + bool non_blocking(const base_implementation_type& impl) const + { + return (impl.state_ & socket_ops::user_set_non_blocking) != 0; + } + + // Sets the non-blocking mode of the socket. + boost::system::error_code non_blocking(base_implementation_type& impl, + bool mode, boost::system::error_code& ec) + { + socket_ops::set_user_non_blocking(impl.socket_, impl.state_, mode, ec); + return ec; + } + + // Gets the non-blocking mode of the native socket implementation. + bool native_non_blocking(const base_implementation_type& impl) const + { + return (impl.state_ & socket_ops::internal_non_blocking) != 0; + } + + // Sets the non-blocking mode of the native socket implementation. + boost::system::error_code native_non_blocking(base_implementation_type& impl, + bool mode, boost::system::error_code& ec) + { + socket_ops::set_internal_non_blocking(impl.socket_, impl.state_, mode, ec); + return ec; + } + + // Disable sends or receives on the socket. + boost::system::error_code shutdown(base_implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) + { + socket_ops::shutdown(impl.socket_, what, ec); + return ec; + } + + // Send the given data to the peer. + template + size_t send(base_implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + buffer_sequence_adapter bufs(buffers); + + return socket_ops::sync_send(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); + } + + // Wait until data can be sent without blocking. + size_t send(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags, boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_write(impl.socket_, impl.state_, ec); + + return 0; + } + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_send(base_implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_send_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, buffers, flags, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send")); + + start_op(impl, reactor::write_op, p.p, is_continuation, true, + ((impl.state_ & socket_ops::stream_oriented) + && buffer_sequence_adapter::all_empty(buffers))); + p.v = p.p = 0; + } + + // Start an asynchronous wait until data can be sent without blocking. + template + void async_send(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_null_buffers_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", + &impl, "async_send(null_buffers)")); + + start_op(impl, reactor::write_op, p.p, is_continuation, false, false); + p.v = p.p = 0; + } + + // Receive some data from the peer. Returns the number of bytes received. + template + size_t receive(base_implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + buffer_sequence_adapter bufs(buffers); + + return socket_ops::sync_recv(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), flags, bufs.all_empty(), ec); + } + + // Wait until data can be received without blocking. + size_t receive(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags, boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_read(impl.socket_, impl.state_, ec); + + return 0; + } + + // Start an asynchronous receive. The buffer for the data being received + // must be valid for the lifetime of the asynchronous operation. + template + void async_receive(base_implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_recv_op_ext_local op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_receive")); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, is_continuation, + (flags & socket_base::message_out_of_band) == 0, + ((impl.state_ & socket_ops::stream_oriented) + && buffer_sequence_adapter::all_empty(buffers))); + p.v = p.p = 0; + } + + // Wait until data can be received without blocking. + template + void async_receive(base_implementation_type& impl, const null_buffers&, + socket_base::message_flags flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_null_buffers_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", + &impl, "async_receive(null_buffers)")); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, is_continuation, false, false); + p.v = p.p = 0; + } + + // Receive some data with associated flags. Returns the number of bytes + // received. + template + size_t receive_with_flags(base_implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags in_flags, + socket_base::message_flags& out_flags, boost::system::error_code& ec) + { + buffer_sequence_adapter bufs(buffers); + + return socket_ops::sync_recvmsg(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), in_flags, out_flags, ec); + } + + // Wait until data can be received without blocking. + size_t receive_with_flags(base_implementation_type& impl, + const null_buffers&, socket_base::message_flags, + socket_base::message_flags& out_flags, boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_read(impl.socket_, impl.state_, ec); + + // Clear out_flags, since we cannot give it any other sensible value when + // performing a null_buffers operation. + out_flags = 0; + + return 0; + } + + // Start an asynchronous receive. The buffer for the data being received + // must be valid for the lifetime of the asynchronous operation. + template + void async_receive_with_flags(base_implementation_type& impl, + const MutableBufferSequence& buffers, socket_base::message_flags in_flags, + socket_base::message_flags& out_flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_recvmsg_op_ext_local op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, buffers, in_flags, out_flags, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", + &impl, "async_receive_with_flags")); + + start_op(impl, + (in_flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, is_continuation, + (in_flags & socket_base::message_out_of_band) == 0, false); + p.v = p.p = 0; + } + + // Wait until data can be received without blocking. + template + void async_receive_with_flags(base_implementation_type& impl, + const null_buffers&, socket_base::message_flags in_flags, + socket_base::message_flags& out_flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_null_buffers_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, + "async_receive_with_flags(null_buffers)")); + + // Clear out_flags, since we cannot give it any other sensible value when + // performing a null_buffers operation. + out_flags = 0; + + start_op(impl, + (in_flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, is_continuation, false, false); + p.v = p.p = 0; + } + +protected: + // Open a new socket implementation. + BOOST_ASIO_DECL boost::system::error_code do_open( + base_implementation_type& impl, int af, + int type, int protocol, boost::system::error_code& ec); + + // Assign a native socket to a socket implementation. + BOOST_ASIO_DECL boost::system::error_code do_assign( + base_implementation_type& impl, int type, + const native_handle_type& native_socket, boost::system::error_code& ec); + + // Start the asynchronous read or write operation. + BOOST_ASIO_DECL void start_op(base_implementation_type& impl, int op_type, + reactor_op* op, bool is_continuation, bool is_non_blocking, bool noop); + + // Start the asynchronous accept operation. + BOOST_ASIO_DECL void start_accept_op(base_implementation_type& impl, + reactor_op* op, bool is_continuation, bool peer_is_open); + + // Start the asynchronous connect operation. + BOOST_ASIO_DECL void start_connect_op(base_implementation_type& impl, + reactor_op* op, bool is_continuation, + const socket_addr_type* addr, size_t addrlen); + + // The selector that performs event demultiplexing for the service. + reactor& reactor_; +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#if defined(BOOST_ASIO_HEADER_ONLY) +# include +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // !defined(BOOST_ASIO_HAS_IOCP) + // && !defined(BOOST_ASIO_WINDOWS_RUNTIME) + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_BASE_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_service_ext.hpp b/implementation/helper/boost/asio/detail/reactive_socket_service_ext.hpp new file mode 100644 index 0000000..133301c --- /dev/null +++ b/implementation/helper/boost/asio/detail/reactive_socket_service_ext.hpp @@ -0,0 +1,462 @@ +// +// detail/reactive_socket_service_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +#if !defined(BOOST_ASIO_HAS_IOCP) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class reactive_socket_service_ext : + public reactive_socket_service_base_ext +{ +public: + // The protocol type. + typedef Protocol protocol_type; + + // The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + // The native type of a socket. + typedef socket_type native_handle_type; + + // The implementation type of the socket. + struct implementation_type : + reactive_socket_service_base_ext::base_implementation_type + { + // Default constructor. + implementation_type() + : protocol_(endpoint_type().protocol()) + { + } + + // The protocol associated with the socket. + protocol_type protocol_; + }; + + // Constructor. + reactive_socket_service_ext(boost::asio::io_service& io_service) + : reactive_socket_service_base_ext(io_service) + { + } + + // Move-construct a new socket implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + this->base_move_construct(impl, other_impl); + + impl.protocol_ = other_impl.protocol_; + other_impl.protocol_ = endpoint_type().protocol(); + } + + // Move-assign from another socket implementation. + void move_assign(implementation_type& impl, + reactive_socket_service_base_ext& other_service, + implementation_type& other_impl) + { + this->base_move_assign(impl, other_service, other_impl); + + impl.protocol_ = other_impl.protocol_; + other_impl.protocol_ = endpoint_type().protocol(); + } + + // Move-construct a new socket implementation from another protocol type. + template + void converting_move_construct(implementation_type& impl, + typename reactive_socket_service_ext< + Protocol1>::implementation_type& other_impl) + { + this->base_move_construct(impl, other_impl); + + impl.protocol_ = protocol_type(other_impl.protocol_); + other_impl.protocol_ = typename Protocol1::endpoint().protocol(); + } + + // Open a new socket implementation. + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) + { + if (!do_open(impl, protocol.family(), + protocol.type(), protocol.protocol(), ec)) + impl.protocol_ = protocol; + return ec; + } + + // Assign a native socket to a socket implementation. + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_handle_type& native_socket, + boost::system::error_code& ec) + { + if (!do_assign(impl, protocol.type(), native_socket, ec)) + impl.protocol_ = protocol; + return ec; + } + + // Get the native socket representation. + native_handle_type native_handle(implementation_type& impl) + { + return impl.socket_; + } + + // Bind the socket to the specified local endpoint. + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) + { + socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); + return ec; + } + + // Set a socket option. + template + boost::system::error_code set_option(implementation_type& impl, + const Option& option, boost::system::error_code& ec) + { + socket_ops::setsockopt(impl.socket_, impl.state_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), option.size(impl.protocol_), ec); + return ec; + } + + // Set a socket option. + template + boost::system::error_code get_option(const implementation_type& impl, + Option& option, boost::system::error_code& ec) const + { + std::size_t size = option.size(impl.protocol_); + socket_ops::getsockopt(impl.socket_, impl.state_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), &size, ec); + if (!ec) + option.resize(impl.protocol_, size); + return ec; + } + + // Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + endpoint_type endpoint; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); + endpoint.resize(addr_len); + return endpoint; + } + + // Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + endpoint_type endpoint; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getpeername(impl.socket_, + endpoint.data(), &addr_len, false, ec)) + return endpoint_type(); + endpoint.resize(addr_len); + return endpoint; + } + + // Send a datagram to the specified endpoint. Returns the number of bytes + // sent. + template + size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + boost::system::error_code& ec) + { + buffer_sequence_adapter bufs(buffers); + + return socket_ops::sync_sendto(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), flags, + destination.data(), destination.size(), ec); + } + + // Wait until data can be sent without blocking. + size_t send_to(implementation_type& impl, const null_buffers&, + const endpoint_type&, socket_base::message_flags, + boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_write(impl.socket_, impl.state_, ec); + + return 0; + } + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_send_to(implementation_type& impl, + const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_sendto_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send_to")); + + start_op(impl, reactor::write_op, p.p, is_continuation, true, false); + p.v = p.p = 0; + } + + // Start an asynchronous wait until data can be sent without blocking. + template + void async_send_to(implementation_type& impl, const null_buffers&, + const endpoint_type&, socket_base::message_flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_null_buffers_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", + &impl, "async_send_to(null_buffers)")); + + start_op(impl, reactor::write_op, p.p, is_continuation, false, false); + p.v = p.p = 0; + } + + // Receive a datagram with the endpoint of the sender. Returns the number of + // bytes received. + template + size_t receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + boost::system::error_code& ec) + { + buffer_sequence_adapter bufs(buffers); + + std::size_t addr_len = sender_endpoint.capacity(); + std::size_t bytes_recvd = socket_ops::sync_recvfrom( + impl.socket_, impl.state_, bufs.buffers(), bufs.count(), + flags, sender_endpoint.data(), &addr_len, ec); + + if (!ec) + sender_endpoint.resize(addr_len); + + return bytes_recvd; + } + + // Wait until data can be received without blocking. + size_t receive_from(implementation_type& impl, const null_buffers&, + endpoint_type& sender_endpoint, socket_base::message_flags, + boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_read(impl.socket_, impl.state_, ec); + + // Reset endpoint since it can be given no sensible value at this time. + sender_endpoint = endpoint_type(); + + return 0; + } + + // Start an asynchronous receive. The buffer for the data being received and + // the sender_endpoint object must both be valid for the lifetime of the + // asynchronous operation. + template + void async_receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_recvfrom_op_ext op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + int protocol = impl.protocol_.type(); + p.p = new (p.v) op(impl.socket_, protocol, + buffers, sender_endpoint, flags, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", + &impl, "async_receive_from")); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, is_continuation, true, false); + p.v = p.p = 0; + } + + // Wait until data can be received without blocking. + template + void async_receive_from(implementation_type& impl, + const null_buffers&, endpoint_type& sender_endpoint, + socket_base::message_flags flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_null_buffers_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", + &impl, "async_receive_from(null_buffers)")); + + // Reset endpoint since it can be given no sensible value at this time. + sender_endpoint = endpoint_type(); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, is_continuation, false, false); + p.v = p.p = 0; + } + + // Accept a new connection. + template + boost::system::error_code accept(implementation_type& impl, + Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) + { + // We cannot accept a socket that is already open. + if (peer.is_open()) + { + ec = boost::asio::error::already_open; + return ec; + } + + std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; + socket_holder new_socket(socket_ops::sync_accept(impl.socket_, + impl.state_, peer_endpoint ? peer_endpoint->data() : 0, + peer_endpoint ? &addr_len : 0, ec)); + + // On success, assign new connection to peer socket object. + if (new_socket.get() != invalid_socket) + { + if (peer_endpoint) + peer_endpoint->resize(addr_len); + if (!peer.assign(impl.protocol_, new_socket.get(), ec)) + new_socket.release(); + } + + return ec; + } + + // Start an asynchronous accept. The peer and peer_endpoint objects + // must be valid until the accept's handler is invoked. + template + void async_accept(implementation_type& impl, Socket& peer, + endpoint_type* peer_endpoint, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_accept_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, impl.state_, peer, + impl.protocol_, peer_endpoint, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_accept")); + + start_accept_op(impl, p.p, is_continuation, peer.is_open()); + p.v = p.p = 0; + } + + // Connect the socket to the specified endpoint. + boost::system::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, boost::system::error_code& ec) + { + socket_ops::sync_connect(impl.socket_, + peer_endpoint.data(), peer_endpoint.size(), ec); + return ec; + } + + // Start an asynchronous connect. + template + void async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_connect_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect")); + + start_connect_op(impl, p.p, is_continuation, + peer_endpoint.data(), peer_endpoint.size()); + p.v = p.p = 0; + } +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // !defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/reactive_socket_service_ext_local.hpp b/implementation/helper/boost/asio/detail/reactive_socket_service_ext_local.hpp new file mode 100644 index 0000000..7b444b3 --- /dev/null +++ b/implementation/helper/boost/asio/detail/reactive_socket_service_ext_local.hpp @@ -0,0 +1,462 @@ +// +// detail/reactive_socket_service_ext_local.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP +#define BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#include + +#if !defined(BOOST_ASIO_HAS_IOCP) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace detail { + +template +class reactive_socket_service_ext_local : + public reactive_socket_service_base_ext_local +{ +public: + // The protocol type. + typedef Protocol protocol_type; + + // The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + + // The native type of a socket. + typedef socket_type native_handle_type; + + // The implementation type of the socket. + struct implementation_type : + reactive_socket_service_base_ext_local::base_implementation_type + { + // Default constructor. + implementation_type() + : protocol_(endpoint_type().protocol()) + { + } + + // The protocol associated with the socket. + protocol_type protocol_; + }; + + // Constructor. + reactive_socket_service_ext_local(boost::asio::io_service& io_service) + : reactive_socket_service_base_ext_local(io_service) + { + } + + // Move-construct a new socket implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + this->base_move_construct(impl, other_impl); + + impl.protocol_ = other_impl.protocol_; + other_impl.protocol_ = endpoint_type().protocol(); + } + + // Move-assign from another socket implementation. + void move_assign(implementation_type& impl, + reactive_socket_service_base_ext_local& other_service, + implementation_type& other_impl) + { + this->base_move_assign(impl, other_service, other_impl); + + impl.protocol_ = other_impl.protocol_; + other_impl.protocol_ = endpoint_type().protocol(); + } + + // Move-construct a new socket implementation from another protocol type. + template + void converting_move_construct(implementation_type& impl, + typename reactive_socket_service_ext_local< + Protocol1>::implementation_type& other_impl) + { + this->base_move_construct(impl, other_impl); + + impl.protocol_ = protocol_type(other_impl.protocol_); + other_impl.protocol_ = typename Protocol1::endpoint().protocol(); + } + + // Open a new socket implementation. + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) + { + if (!do_open(impl, protocol.family(), + protocol.type(), protocol.protocol(), ec)) + impl.protocol_ = protocol; + return ec; + } + + // Assign a native socket to a socket implementation. + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_handle_type& native_socket, + boost::system::error_code& ec) + { + if (!do_assign(impl, protocol.type(), native_socket, ec)) + impl.protocol_ = protocol; + return ec; + } + + // Get the native socket representation. + native_handle_type native_handle(implementation_type& impl) + { + return impl.socket_; + } + + // Bind the socket to the specified local endpoint. + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) + { + socket_ops::bind(impl.socket_, endpoint.data(), endpoint.size(), ec); + return ec; + } + + // Set a socket option. + template + boost::system::error_code set_option(implementation_type& impl, + const Option& option, boost::system::error_code& ec) + { + socket_ops::setsockopt(impl.socket_, impl.state_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), option.size(impl.protocol_), ec); + return ec; + } + + // Set a socket option. + template + boost::system::error_code get_option(const implementation_type& impl, + Option& option, boost::system::error_code& ec) const + { + std::size_t size = option.size(impl.protocol_); + socket_ops::getsockopt(impl.socket_, impl.state_, + option.level(impl.protocol_), option.name(impl.protocol_), + option.data(impl.protocol_), &size, ec); + if (!ec) + option.resize(impl.protocol_, size); + return ec; + } + + // Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + endpoint_type endpoint; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec)) + return endpoint_type(); + endpoint.resize(addr_len); + return endpoint; + } + + // Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + endpoint_type endpoint; + std::size_t addr_len = endpoint.capacity(); + if (socket_ops::getpeername(impl.socket_, + endpoint.data(), &addr_len, false, ec)) + return endpoint_type(); + endpoint.resize(addr_len); + return endpoint; + } + + // Send a datagram to the specified endpoint. Returns the number of bytes + // sent. + template + size_t send_to(implementation_type& impl, const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + boost::system::error_code& ec) + { + buffer_sequence_adapter bufs(buffers); + + return socket_ops::sync_sendto(impl.socket_, impl.state_, + bufs.buffers(), bufs.count(), flags, + destination.data(), destination.size(), ec); + } + + // Wait until data can be sent without blocking. + size_t send_to(implementation_type& impl, const null_buffers&, + const endpoint_type&, socket_base::message_flags, + boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_write(impl.socket_, impl.state_, ec); + + return 0; + } + + // Start an asynchronous send. The data being sent must be valid for the + // lifetime of the asynchronous operation. + template + void async_send_to(implementation_type& impl, + const ConstBufferSequence& buffers, + const endpoint_type& destination, socket_base::message_flags flags, + Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_sendto_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, buffers, destination, flags, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_send_to")); + + start_op(impl, reactor::write_op, p.p, is_continuation, true, false); + p.v = p.p = 0; + } + + // Start an asynchronous wait until data can be sent without blocking. + template + void async_send_to(implementation_type& impl, const null_buffers&, + const endpoint_type&, socket_base::message_flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_null_buffers_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", + &impl, "async_send_to(null_buffers)")); + + start_op(impl, reactor::write_op, p.p, is_continuation, false, false); + p.v = p.p = 0; + } + + // Receive a datagram with the endpoint of the sender. Returns the number of + // bytes received. + template + size_t receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, + endpoint_type& sender_endpoint, socket_base::message_flags flags, + boost::system::error_code& ec) + { + buffer_sequence_adapter bufs(buffers); + + std::size_t addr_len = sender_endpoint.capacity(); + std::size_t bytes_recvd = socket_ops::sync_recvfrom( + impl.socket_, impl.state_, bufs.buffers(), bufs.count(), + flags, sender_endpoint.data(), &addr_len, ec); + + if (!ec) + sender_endpoint.resize(addr_len); + + return bytes_recvd; + } + + // Wait until data can be received without blocking. + size_t receive_from(implementation_type& impl, const null_buffers&, + endpoint_type& sender_endpoint, socket_base::message_flags, + boost::system::error_code& ec) + { + // Wait for socket to become ready. + socket_ops::poll_read(impl.socket_, impl.state_, ec); + + // Reset endpoint since it can be given no sensible value at this time. + sender_endpoint = endpoint_type(); + + return 0; + } + + // Start an asynchronous receive. The buffer for the data being received and + // the sender_endpoint object must both be valid for the lifetime of the + // asynchronous operation. + template + void async_receive_from(implementation_type& impl, + const MutableBufferSequence& buffers, endpoint_type& sender_endpoint, + socket_base::message_flags flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_recvfrom_op_ext_local op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + int protocol = impl.protocol_.type(); + p.p = new (p.v) op(impl.socket_, protocol, + buffers, sender_endpoint, flags, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", + &impl, "async_receive_from")); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, is_continuation, true, false); + p.v = p.p = 0; + } + + // Wait until data can be received without blocking. + template + void async_receive_from(implementation_type& impl, + const null_buffers&, endpoint_type& sender_endpoint, + socket_base::message_flags flags, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_null_buffers_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", + &impl, "async_receive_from(null_buffers)")); + + // Reset endpoint since it can be given no sensible value at this time. + sender_endpoint = endpoint_type(); + + start_op(impl, + (flags & socket_base::message_out_of_band) + ? reactor::except_op : reactor::read_op, + p.p, is_continuation, false, false); + p.v = p.p = 0; + } + + // Accept a new connection. + template + boost::system::error_code accept(implementation_type& impl, + Socket& peer, endpoint_type* peer_endpoint, boost::system::error_code& ec) + { + // We cannot accept a socket that is already open. + if (peer.is_open()) + { + ec = boost::asio::error::already_open; + return ec; + } + + std::size_t addr_len = peer_endpoint ? peer_endpoint->capacity() : 0; + socket_holder new_socket(socket_ops::sync_accept(impl.socket_, + impl.state_, peer_endpoint ? peer_endpoint->data() : 0, + peer_endpoint ? &addr_len : 0, ec)); + + // On success, assign new connection to peer socket object. + if (new_socket.get() != invalid_socket) + { + if (peer_endpoint) + peer_endpoint->resize(addr_len); + if (!peer.assign(impl.protocol_, new_socket.get(), ec)) + new_socket.release(); + } + + return ec; + } + + // Start an asynchronous accept. The peer and peer_endpoint objects + // must be valid until the accept's handler is invoked. + template + void async_accept(implementation_type& impl, Socket& peer, + endpoint_type* peer_endpoint, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_accept_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, impl.state_, peer, + impl.protocol_, peer_endpoint, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_accept")); + + start_accept_op(impl, p.p, is_continuation, peer.is_open()); + p.v = p.p = 0; + } + + // Connect the socket to the specified endpoint. + boost::system::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, boost::system::error_code& ec) + { + socket_ops::sync_connect(impl.socket_, + peer_endpoint.data(), peer_endpoint.size(), ec); + return ec; + } + + // Start an asynchronous connect. + template + void async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, Handler& handler) + { + bool is_continuation = + boost_asio_handler_cont_helpers::is_continuation(handler); + + // Allocate and construct an operation to wrap the handler. + typedef reactive_socket_connect_op op; + typename op::ptr p = { boost::asio::detail::addressof(handler), + boost_asio_handler_alloc_helpers::allocate( + sizeof(op), handler), 0 }; + p.p = new (p.v) op(impl.socket_, handler); + + BOOST_ASIO_HANDLER_CREATION((p.p, "socket", &impl, "async_connect")); + + start_connect_op(impl, p.p, is_continuation, + peer_endpoint.data(), peer_endpoint.size()); + p.v = p.p = 0; + } +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#include + +#endif // !defined(BOOST_ASIO_HAS_IOCP) + +#endif // BOOST_ASIO_DETAIL_REACTIVE_SOCKET_SERVICE_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/reactor_op_ext.hpp b/implementation/helper/boost/asio/detail/reactor_op_ext.hpp new file mode 100644 index 0000000..948e016 --- /dev/null +++ b/implementation/helper/boost/asio/detail/reactor_op_ext.hpp @@ -0,0 +1,42 @@ +// +// detail/reactor_op_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP +#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +namespace boost { +namespace asio { +namespace detail { + +class reactor_op_ext + : public reactor_op +{ +public: + // The destination address + boost::asio::ip::address da_; + + reactor_op_ext(perform_func_type perform_func, func_type complete_func) + : reactor_op(perform_func, complete_func) + { + } +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_HPP diff --git a/implementation/helper/boost/asio/detail/reactor_op_ext_local.hpp b/implementation/helper/boost/asio/detail/reactor_op_ext_local.hpp new file mode 100644 index 0000000..a10d876 --- /dev/null +++ b/implementation/helper/boost/asio/detail/reactor_op_ext_local.hpp @@ -0,0 +1,43 @@ +// +// detail/reactor_op_ext_local.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP +#define BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +namespace boost { +namespace asio { +namespace detail { + +class reactor_op_ext_local + : public reactor_op +{ +public: + // The passed credentials + std::uint32_t uid_; + std::uint32_t gid_; + + reactor_op_ext_local(perform_func_type perform_func, func_type complete_func) + : reactor_op(perform_func, complete_func) + { + } +}; + +} // namespace detail +} // namespace asio +} // namespace boost + +#endif // BOOST_ASIO_DETAIL_REACTOR_OP_EXT_LOCAL_HPP diff --git a/implementation/helper/boost/asio/detail/socket_ops_ext.hpp b/implementation/helper/boost/asio/detail/socket_ops_ext.hpp new file mode 100644 index 0000000..65b8ad8 --- /dev/null +++ b/implementation/helper/boost/asio/detail/socket_ops_ext.hpp @@ -0,0 +1,62 @@ +// +// detail/socket_ops_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP +#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +namespace boost { +namespace asio { +namespace detail { +namespace socket_ops { + +BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, + size_t count, int flags, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec, + boost::asio::ip::address& da); + +BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, + buf* bufs, size_t count, int flags, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec, boost::asio::ip::address& da); + +#if defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL void complete_iocp_recvfrom( + const weak_cancel_token_type& cancel_token, + boost::system::error_code& ec, + boost::asio::ip::address& da); + +#else // defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, + buf* bufs, size_t count, int flags, + socket_addr_type* addr, std::size_t* addrlen, + boost::system::error_code& ec, size_t& bytes_transferred, + boost::asio::ip::address& da); + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +} // namespace socket_ops +} // namespace detail +} // namespace asio +} // namespace boost + + +#if defined(BOOST_ASIO_HEADER_ONLY) +# include +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/boost/asio/detail/socket_ops_ext_local.hpp b/implementation/helper/boost/asio/detail/socket_ops_ext_local.hpp new file mode 100644 index 0000000..77fd563 --- /dev/null +++ b/implementation/helper/boost/asio/detail/socket_ops_ext_local.hpp @@ -0,0 +1,72 @@ +// +// detail/socket_ops_ext_local.hpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP +#define BOOST_ASIO_DETAIL_SOCKET_OPS_EXT_LOCAL_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +namespace boost { +namespace asio { +namespace detail { +namespace socket_ops { + +BOOST_ASIO_DECL signed_size_type recv(socket_type s, buf* bufs, + size_t count, int flags, boost::system::error_code& ec, + std::uint32_t& uid, std::uint32_t& gid); + +BOOST_ASIO_DECL signed_size_type recvfrom(socket_type s, buf* bufs, + size_t count, int flags, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec, + std::uint32_t& uid, std::uint32_t& gid); + +BOOST_ASIO_DECL size_t sync_recvfrom(socket_type s, state_type state, + buf* bufs, size_t count, int flags, socket_addr_type* addr, + std::size_t* addrlen, boost::system::error_code& ec, + std::uint32_t& uid, std::uint32_t& gid); + +#if defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL void complete_iocp_recvfrom( + const weak_cancel_token_type& cancel_token, + boost::system::error_code& ec, + std::uint32_t& uid, std::uint32_t& gid); + +#else // defined(BOOST_ASIO_HAS_IOCP) + +BOOST_ASIO_DECL bool non_blocking_recv(socket_type s, + buf* bufs, size_t count, int flags, bool is_stream, + boost::system::error_code& ec, size_t& bytes_transferred, + std::uint32_t& uid, std::uint32_t& gid); + +BOOST_ASIO_DECL bool non_blocking_recvfrom(socket_type s, + buf* bufs, size_t count, int flags, + socket_addr_type* addr, std::size_t* addrlen, + boost::system::error_code& ec, size_t& bytes_transferred, + std::uint32_t& uid, std::uint32_t& gid); + +#endif // defined(BOOST_ASIO_HAS_IOCP) + +} // namespace socket_ops +} // namespace detail +} // namespace asio +} // namespace boost + + +#if defined(BOOST_ASIO_HEADER_ONLY) +# include +#endif // defined(BOOST_ASIO_HEADER_ONLY) + +#endif // BOOST_EXT_ASIO_DETAIL_SOCKET_OPS_HPP diff --git a/implementation/helper/boost/asio/ip/udp_ext.hpp b/implementation/helper/boost/asio/ip/udp_ext.hpp new file mode 100644 index 0000000..c622ff9 --- /dev/null +++ b/implementation/helper/boost/asio/ip/udp_ext.hpp @@ -0,0 +1,115 @@ +// +// ip/udp_ext.hpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_boost or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_IP_UDP_EXT_HPP +#define BOOST_ASIO_IP_UDP_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace ip { + +/// Encapsulates the flags needed for UDP. +/** + * The boost::asio::ip::udp_ext class contains flags necessary for UDP sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol, InternetProtocol. + */ +class udp_ext +{ +public: + /// The type of a UDP endpoint. + typedef basic_endpoint endpoint; + + /// Construct to represent the IPv4 UDP protocol. + static udp_ext v4() + { + return udp_ext(BOOST_ASIO_OS_DEF(AF_INET)); + } + + /// Construct to represent the IPv6 UDP protocol. + static udp_ext v6() + { + return udp_ext(BOOST_ASIO_OS_DEF(AF_INET6)); + } + + /// Obtain an identifier for the type of the protocol. + int type() const + { + return BOOST_ASIO_OS_DEF(SOCK_DGRAM); + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return BOOST_ASIO_OS_DEF(IPPROTO_UDP); + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return family_; + } + + /// The UDP socket type. + typedef basic_datagram_socket_ext socket; + + /// The UDP resolver type. + typedef basic_resolver resolver; + + /// Compare two protocols for equality. + friend bool operator==(const udp_ext& p1, const udp_ext& p2) + { + return p1.family_ == p2.family_; + } + + /// Compare two protocols for inequality. + friend bool operator!=(const udp_ext& p1, const udp_ext& p2) + { + return p1.family_ != p2.family_; + } + +private: + // Construct with a specific family. + explicit udp_ext(int protocol_family) + : family_(protocol_family) + { + } + + int family_; +}; + +} // namespace ip +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_IP_UDP_EXT_HPP diff --git a/implementation/helper/boost/asio/local/stream_protocol_ext.hpp b/implementation/helper/boost/asio/local/stream_protocol_ext.hpp new file mode 100644 index 0000000..6ccd0ad --- /dev/null +++ b/implementation/helper/boost/asio/local/stream_protocol_ext.hpp @@ -0,0 +1,93 @@ +// +// local/stream_protocol_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP +#define BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include + +#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) \ + || defined(GENERATING_DOCUMENTATION) + +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace asio { +namespace local { + +/// Encapsulates the flags needed for stream-oriented UNIX sockets. +/** + * The boost::asio::local::stream_protocol class contains flags necessary for + * stream-oriented UNIX domain sockets. + * + * @par Thread Safety + * @e Distinct @e objects: Safe.@n + * @e Shared @e objects: Safe. + * + * @par Concepts: + * Protocol. + */ +class stream_protocol_ext +{ +public: + /// Obtain an identifier for the type of the protocol. + int type() const + { + return SOCK_STREAM; + } + + /// Obtain an identifier for the protocol. + int protocol() const + { + return 0; + } + + /// Obtain an identifier for the protocol family. + int family() const + { + return AF_UNIX; + } + + /// The type of a UNIX domain endpoint. + typedef basic_endpoint endpoint; + + /// The UNIX domain socket type. + typedef basic_stream_socket_ext socket; + + /// The UNIX domain acceptor type. + typedef basic_socket_acceptor_ext acceptor; + +#if !defined(BOOST_ASIO_NO_IOSTREAM) + /// The UNIX domain iostream type. + typedef basic_socket_iostream iostream; +#endif // !defined(BOOST_ASIO_NO_IOSTREAM) +}; + +} // namespace local +} // namespace asio +} // namespace boost + +#include + +#endif // defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) + // || defined(GENERATING_DOCUMENTATION) + +#endif // BOOST_ASIO_LOCAL_STREAM_PROTOCOL_EXT_HPP diff --git a/implementation/helper/boost/asio/socket_acceptor_service_ext.hpp b/implementation/helper/boost/asio/socket_acceptor_service_ext.hpp new file mode 100644 index 0000000..19a3bde --- /dev/null +++ b/implementation/helper/boost/asio/socket_acceptor_service_ext.hpp @@ -0,0 +1,305 @@ +// +// socket_acceptor_service_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_EXT_HPP +#define BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include + +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) +# include +#elif defined(BOOST_ASIO_HAS_IOCP) +# include +#else +# include +#endif + +#include + +namespace boost { +namespace asio { + +/// Default service implementation for a socket acceptor. +template +class socket_acceptor_service_ext +#if defined(GENERATING_DOCUMENTATION) + : public boost::asio::io_service::service +#else + : public boost::asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static boost::asio::io_service::id id; +#endif + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename protocol_type::endpoint endpoint_type; + +private: + // The type of the platform-specific implementation. +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + typedef detail::null_socket_service service_impl_type; +#elif defined(BOOST_ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#else + typedef detail::reactive_socket_service_ext service_impl_type; +#endif + +public: + /// The native type of the socket acceptor. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// (Deprecated: Use native_handle_type.) The native acceptor type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef typename service_impl_type::native_handle_type native_type; +#endif + + /// The native acceptor type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef typename service_impl_type::native_handle_type native_handle_type; +#endif + + /// Construct a new socket acceptor service for the specified io_service. + explicit socket_acceptor_service_ext(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + socket_acceptor_service_ext >(io_service), + service_impl_(io_service) + { + } + + /// Construct a new socket acceptor implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new socket acceptor implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another socket acceptor implementation. + void move_assign(implementation_type& impl, + socket_acceptor_service_ext& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } + + /// Move-construct a new socket acceptor implementation from another protocol + /// type. + template + void converting_move_construct(implementation_type& impl, + typename socket_acceptor_service_ext< + Protocol1>::implementation_type& other_impl, + typename enable_if::value>::type* = 0) + { + service_impl_.template converting_move_construct( + impl, other_impl); + } +#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a socket acceptor implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Open a new socket acceptor implementation. + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) + { + return service_impl_.open(impl, protocol, ec); + } + + /// Assign an existing native acceptor to a socket acceptor. + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_handle_type& native_acceptor, + boost::system::error_code& ec) + { + return service_impl_.assign(impl, protocol, native_acceptor, ec); + } + + /// Determine whether the acceptor is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Cancel all asynchronous operations associated with the acceptor. + boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Bind the socket acceptor to the specified local endpoint. + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) + { + return service_impl_.bind(impl, endpoint, ec); + } + + /// Place the socket acceptor into the state where it will listen for new + /// connections. + boost::system::error_code listen(implementation_type& impl, int backlog, + boost::system::error_code& ec) + { + return service_impl_.listen(impl, backlog, ec); + } + + /// Close a socket acceptor implementation. + boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// (Deprecated: Use native_handle().) Get the native acceptor implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Get the native acceptor implementation. + native_handle_type native_handle(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Set a socket option. + template + boost::system::error_code set_option(implementation_type& impl, + const SettableSocketOption& option, boost::system::error_code& ec) + { + return service_impl_.set_option(impl, option, ec); + } + + /// Get a socket option. + template + boost::system::error_code get_option(const implementation_type& impl, + GettableSocketOption& option, boost::system::error_code& ec) const + { + return service_impl_.get_option(impl, option, ec); + } + + /// Perform an IO control command on the socket. + template + boost::system::error_code io_control(implementation_type& impl, + IoControlCommand& command, boost::system::error_code& ec) + { + return service_impl_.io_control(impl, command, ec); + } + + /// Gets the non-blocking mode of the acceptor. + bool non_blocking(const implementation_type& impl) const + { + return service_impl_.non_blocking(impl); + } + + /// Sets the non-blocking mode of the acceptor. + boost::system::error_code non_blocking(implementation_type& impl, + bool mode, boost::system::error_code& ec) + { + return service_impl_.non_blocking(impl, mode, ec); + } + + /// Gets the non-blocking mode of the native acceptor implementation. + bool native_non_blocking(const implementation_type& impl) const + { + return service_impl_.native_non_blocking(impl); + } + + /// Sets the non-blocking mode of the native acceptor implementation. + boost::system::error_code native_non_blocking(implementation_type& impl, + bool mode, boost::system::error_code& ec) + { + return service_impl_.native_non_blocking(impl, mode, ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Accept a new connection. + template + boost::system::error_code accept(implementation_type& impl, + basic_socket& peer, + endpoint_type* peer_endpoint, boost::system::error_code& ec, + typename enable_if::value>::type* = 0) + { + return service_impl_.accept(impl, peer, peer_endpoint, ec); + } + + /// Start an asynchronous accept. + template + BOOST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, + void (boost::system::error_code)) + async_accept(implementation_type& impl, + basic_socket& peer, + endpoint_type* peer_endpoint, + BOOST_ASIO_MOVE_ARG(AcceptHandler) handler, + typename enable_if::value>::type* = 0) + { + detail::async_result_init< + AcceptHandler, void (boost::system::error_code)> init( + BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); + + service_impl_.async_accept(impl, peer, peer_endpoint, init.handler); + + return init.result.get(); + } + +private: + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + service_impl_.shutdown_service(); + } + + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_SOCKET_ACCEPTOR_SERVICE_EXT_HPP diff --git a/implementation/helper/boost/asio/stream_socket_service_ext.hpp b/implementation/helper/boost/asio/stream_socket_service_ext.hpp new file mode 100644 index 0000000..aaa13b3 --- /dev/null +++ b/implementation/helper/boost/asio/stream_socket_service_ext.hpp @@ -0,0 +1,379 @@ +// +// stream_socket_service_ext.hpp +// ~~~~~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (C) 2016-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP +#define BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP + +#if defined(_MSC_VER) && (_MSC_VER >= 1200) +# pragma once +#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) + +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) +# include +#elif defined(BOOST_ASIO_HAS_IOCP) +# include +#else +# include +#endif + +#include + +namespace boost { +namespace asio { + +/// Default service implementation for a stream socket. +template +class stream_socket_service_ext +#if defined(GENERATING_DOCUMENTATION) + : public boost::asio::io_service::service +#else + : public boost::asio::detail::service_base > +#endif +{ +public: +#if defined(GENERATING_DOCUMENTATION) + /// The unique service identifier. + static boost::asio::io_service::id id; +#endif + + /// The protocol type. + typedef Protocol protocol_type; + + /// The endpoint type. + typedef typename Protocol::endpoint endpoint_type; + +private: + // The type of the platform-specific implementation. +#if defined(BOOST_ASIO_WINDOWS_RUNTIME) + typedef detail::winrt_ssocket_service service_impl_type; +#elif defined(BOOST_ASIO_HAS_IOCP) + typedef detail::win_iocp_socket_service service_impl_type; +#else + typedef detail::reactive_socket_service_ext_local service_impl_type; +#endif + +public: + /// The type of a stream socket implementation. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined implementation_type; +#else + typedef typename service_impl_type::implementation_type implementation_type; +#endif + + /// (Deprecated: Use native_handle_type.) The native socket type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_type; +#else + typedef typename service_impl_type::native_handle_type native_type; +#endif + + /// The native socket type. +#if defined(GENERATING_DOCUMENTATION) + typedef implementation_defined native_handle_type; +#else + typedef typename service_impl_type::native_handle_type native_handle_type; +#endif + + /// Construct a new stream socket service for the specified io_service. + explicit stream_socket_service_ext(boost::asio::io_service& io_service) + : boost::asio::detail::service_base< + stream_socket_service_ext >(io_service), + service_impl_(io_service) + { + } + + /// Construct a new stream socket implementation. + void construct(implementation_type& impl) + { + service_impl_.construct(impl); + } + +#if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + /// Move-construct a new stream socket implementation. + void move_construct(implementation_type& impl, + implementation_type& other_impl) + { + service_impl_.move_construct(impl, other_impl); + } + + /// Move-assign from another stream socket implementation. + void move_assign(implementation_type& impl, + stream_socket_service_ext& other_service, + implementation_type& other_impl) + { + service_impl_.move_assign(impl, other_service.service_impl_, other_impl); + } + + /// Move-construct a new stream socket implementation from another protocol + /// type. + template + void converting_move_construct(implementation_type& impl, + typename stream_socket_service_ext< + Protocol1>::implementation_type& other_impl, + typename enable_if::value>::type* = 0) + { + service_impl_.template converting_move_construct( + impl, other_impl); + } +#endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + + /// Destroy a stream socket implementation. + void destroy(implementation_type& impl) + { + service_impl_.destroy(impl); + } + + /// Open a stream socket. + boost::system::error_code open(implementation_type& impl, + const protocol_type& protocol, boost::system::error_code& ec) + { + if (protocol.type() == BOOST_ASIO_OS_DEF(SOCK_STREAM)) + service_impl_.open(impl, protocol, ec); + else + ec = boost::asio::error::invalid_argument; + return ec; + } + + /// Assign an existing native socket to a stream socket. + boost::system::error_code assign(implementation_type& impl, + const protocol_type& protocol, const native_handle_type& native_socket, + boost::system::error_code& ec) + { + return service_impl_.assign(impl, protocol, native_socket, ec); + } + + /// Determine whether the socket is open. + bool is_open(const implementation_type& impl) const + { + return service_impl_.is_open(impl); + } + + /// Close a stream socket implementation. + boost::system::error_code close(implementation_type& impl, + boost::system::error_code& ec) + { + return service_impl_.close(impl, ec); + } + + /// (Deprecated: Use native_handle().) Get the native socket implementation. + native_type native(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Get the native socket implementation. + native_handle_type native_handle(implementation_type& impl) + { + return service_impl_.native_handle(impl); + } + + /// Cancel all asynchronous operations associated with the socket. + boost::system::error_code cancel(implementation_type& impl, + boost::system::error_code& ec) + { + return service_impl_.cancel(impl, ec); + } + + /// Determine whether the socket is at the out-of-band data mark. + bool at_mark(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.at_mark(impl, ec); + } + + /// Determine the number of bytes available for reading. + std::size_t available(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.available(impl, ec); + } + + /// Bind the stream socket to the specified local endpoint. + boost::system::error_code bind(implementation_type& impl, + const endpoint_type& endpoint, boost::system::error_code& ec) + { + return service_impl_.bind(impl, endpoint, ec); + } + + /// Connect the stream socket to the specified endpoint. + boost::system::error_code connect(implementation_type& impl, + const endpoint_type& peer_endpoint, boost::system::error_code& ec) + { + return service_impl_.connect(impl, peer_endpoint, ec); + } + + /// Start an asynchronous connect. + template + BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, + void (boost::system::error_code)) + async_connect(implementation_type& impl, + const endpoint_type& peer_endpoint, + BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) + { + detail::async_result_init< + ConnectHandler, void (boost::system::error_code)> init( + BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); + + service_impl_.async_connect(impl, peer_endpoint, init.handler); + + return init.result.get(); + } + + /// Set a socket option. + template + boost::system::error_code set_option(implementation_type& impl, + const SettableSocketOption& option, boost::system::error_code& ec) + { + return service_impl_.set_option(impl, option, ec); + } + + /// Get a socket option. + template + boost::system::error_code get_option(const implementation_type& impl, + GettableSocketOption& option, boost::system::error_code& ec) const + { + return service_impl_.get_option(impl, option, ec); + } + + /// Perform an IO control command on the socket. + template + boost::system::error_code io_control(implementation_type& impl, + IoControlCommand& command, boost::system::error_code& ec) + { + return service_impl_.io_control(impl, command, ec); + } + + /// Gets the non-blocking mode of the socket. + bool non_blocking(const implementation_type& impl) const + { + return service_impl_.non_blocking(impl); + } + + /// Sets the non-blocking mode of the socket. + boost::system::error_code non_blocking(implementation_type& impl, + bool mode, boost::system::error_code& ec) + { + return service_impl_.non_blocking(impl, mode, ec); + } + + /// Gets the non-blocking mode of the native socket implementation. + bool native_non_blocking(const implementation_type& impl) const + { + return service_impl_.native_non_blocking(impl); + } + + /// Sets the non-blocking mode of the native socket implementation. + boost::system::error_code native_non_blocking(implementation_type& impl, + bool mode, boost::system::error_code& ec) + { + return service_impl_.native_non_blocking(impl, mode, ec); + } + + /// Get the local endpoint. + endpoint_type local_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.local_endpoint(impl, ec); + } + + /// Get the remote endpoint. + endpoint_type remote_endpoint(const implementation_type& impl, + boost::system::error_code& ec) const + { + return service_impl_.remote_endpoint(impl, ec); + } + + /// Disable sends or receives on the socket. + boost::system::error_code shutdown(implementation_type& impl, + socket_base::shutdown_type what, boost::system::error_code& ec) + { + return service_impl_.shutdown(impl, what, ec); + } + + /// Send the given data to the peer. + template + std::size_t send(implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return service_impl_.send(impl, buffers, flags, ec); + } + + /// Start an asynchronous send. + template + BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, + void (boost::system::error_code, std::size_t)) + async_send(implementation_type& impl, + const ConstBufferSequence& buffers, + socket_base::message_flags flags, + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) + { + detail::async_result_init< + WriteHandler, void (boost::system::error_code, std::size_t)> init( + BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); + + service_impl_.async_send(impl, buffers, flags, init.handler); + + return init.result.get(); + } + + /// Receive some data from the peer. + template + std::size_t receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, boost::system::error_code& ec) + { + return service_impl_.receive(impl, buffers, flags, ec); + } + + /// Start an asynchronous receive. + template + BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, + void (boost::system::error_code, std::size_t, std::uint32_t, std::uint32_t)) + async_receive(implementation_type& impl, + const MutableBufferSequence& buffers, + socket_base::message_flags flags, + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) + { + detail::async_result_init< + ReadHandler, void (boost::system::error_code, std::size_t)> init( + BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); + + service_impl_.async_receive(impl, buffers, flags, init.handler); + + return init.result.get(); + } + +private: + // Destroy all user-defined handler objects owned by the service. + void shutdown_service() + { + service_impl_.shutdown_service(); + } + + // The platform-specific implementation. + service_impl_type service_impl_; +}; + +} // namespace asio +} // namespace boost + +#include + +#endif // BOOST_ASIO_STREAM_SOCKET_SERVICE_EXT_HPP diff --git a/implementation/logger/include/logger_impl.hpp b/implementation/logger/include/logger_impl.hpp index bb83363..c827bf4 100644 --- a/implementation/logger/include/logger_impl.hpp +++ b/implementation/logger/include/logger_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,8 +10,10 @@ #include #ifdef USE_DLT +#ifndef ANDROID #include #endif +#endif #include @@ -43,7 +45,9 @@ private: std::shared_ptr configuration_; #ifdef USE_DLT - DLT_DECLARE_CONTEXT(dlt_); +#ifndef ANDROID + DLT_DECLARE_CONTEXT(dlt_) +#endif #endif }; diff --git a/implementation/logger/src/logger_impl.cpp b/implementation/logger/src/logger_impl.cpp index 7e79aa2..b909c34 100644 --- a/implementation/logger/src/logger_impl.cpp +++ b/implementation/logger/src/logger_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -25,18 +25,22 @@ logger_impl::init(const std::shared_ptr &_configuration) { # define VSOMEIP_LOG_DEFAULT_CONTEXT_ID "VSIP" # define VSOMEIP_LOG_DEFAULT_CONTEXT_NAME "vSomeIP context" +#ifndef ANDROID std::string its_context_id = runtime::get_property("LogContext"); if (its_context_id == "") its_context_id = VSOMEIP_LOG_DEFAULT_CONTEXT_ID; DLT_REGISTER_CONTEXT(its_logger->dlt_, its_context_id.c_str(), VSOMEIP_LOG_DEFAULT_CONTEXT_NAME); #endif +#endif } logger_impl::~logger_impl() { #ifdef USE_DLT +#ifndef ANDROID DLT_UNREGISTER_CONTEXT(dlt_); #endif +#endif } std::shared_ptr @@ -45,6 +49,7 @@ logger_impl::get_configuration() const { } #ifdef USE_DLT +#ifndef ANDROID void logger_impl::log(level_e _level, const char *_data) { @@ -76,13 +81,14 @@ logger_impl::log(level_e _level, const char *_data) { DLT_LOG_STRING(dlt_, its_level, _data); } #endif +#endif static std::shared_ptr *the_logger_ptr__(nullptr); static std::mutex the_logger_mutex__; std::shared_ptr logger_impl::get() { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) std::lock_guard its_lock(the_logger_mutex__); #endif if (the_logger_ptr__ == nullptr) { @@ -97,12 +103,15 @@ logger_impl::get() { return (nullptr); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) static void logger_impl_teardown(void) __attribute__((destructor)); static void logger_impl_teardown(void) { + // TODO: This mutex is causing a crash due to changes in the way mutexes are defined. + // Since this function only runs on the main thread, no mutex should be needed. Leaving a + // comment pending a refactor. + // std::lock_guard its_lock(the_logger_mutex__); if (the_logger_ptr__ != nullptr) { - std::lock_guard its_lock(the_logger_mutex__); the_logger_ptr__->reset(); delete the_logger_ptr__; the_logger_ptr__ = nullptr; diff --git a/implementation/logger/src/message.cpp b/implementation/logger/src/message.cpp index 6787452..b89816c 100644 --- a/implementation/logger/src/message.cpp +++ b/implementation/logger/src/message.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,14 +10,57 @@ #include #ifdef ANDROID -#include +#include -#ifndef LOG_TAG -#define LOG_TAG NULL +#ifdef ALOGE +#undef ALOGE #endif + +#define ALOGE(LOG_TAG, ...) ((void)ALOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGE ALOGE +#endif + +#ifdef ALOGW +#undef ALOGW +#endif + +#define ALOGW(LOG_TAG, ...) ((void)ALOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGW ALOGW +#endif + +#ifdef ALOGI +#undef ALOGI +#endif + +#define ALOGI(LOG_TAG, ...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGI ALOGI +#endif + +#ifdef ALOGD +#undef ALOGD +#endif + +#define ALOGD(LOG_TAG, ...) ((void)ALOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGD ALOGD +#endif + +#ifdef ALOGV +#undef ALOGV +#endif + +#define ALOGV(LOG_TAG, ...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGV ALOGV +#endif + #endif #include +#include #include "../include/logger_impl.hpp" #include "../../configuration/include/configuration.hpp" @@ -34,7 +77,7 @@ message::message(level_e _level) when_ = std::chrono::system_clock::now(); } -message::~message() { +message::~message() try { std::lock_guard its_lock(mutex__); auto its_logger = logger_impl::get(); auto its_configuration = its_logger->get_configuration(); @@ -75,44 +118,47 @@ message::~message() { // Prepare time stamp auto its_time_t = std::chrono::system_clock::to_time_t(when_); - auto its_time = std::localtime(&its_time_t); + struct tm its_time; + localtime_r(&its_time_t, &its_time); auto its_ms = (when_.time_since_epoch().count() / 100) % 1000000; if (its_configuration->has_console_log()) { #ifndef ANDROID std::cout - << std::dec << std::setw(4) << its_time->tm_year + 1900 << "-" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mon + 1 << "-" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mday << " " - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_hour << ":" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_min << ":" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_sec << "." + << std::dec << std::setw(4) << its_time.tm_year + 1900 << "-" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_mon + 1 << "-" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_mday << " " + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_hour << ":" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_min << ":" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_sec << "." << std::dec << std::setw(6) << std::setfill('0') << its_ms << " [" << its_level << "] " << buffer_.data_.str() << std::endl; #else + std::string app = runtime::get_property("LogApplication"); + switch (level_) { case level_e::LL_FATAL: - (void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGE(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_ERROR: - (void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGE(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_WARNING: - (void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGW(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_INFO: - (void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGI(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_DEBUG: - (void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGD(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; case level_e::LL_VERBOSE: - (void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGV(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); break; default: - (void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "%s", buffer_.data_.str().c_str()); + ALOGI(app.c_str(), ("VSIP: " + buffer_.data_.str()).c_str()); }; #endif // !ANDROID } @@ -123,12 +169,12 @@ message::~message() { std::ios_base::app); if (its_logfile.is_open()) { its_logfile - << std::dec << std::setw(4) << its_time->tm_year + 1900 << "-" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mon + 1 << "-" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_mday << " " - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_hour << ":" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_min << ":" - << std::dec << std::setw(2) << std::setfill('0') << its_time->tm_sec << "." + << std::dec << std::setw(4) << its_time.tm_year + 1900 << "-" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_mon + 1 << "-" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_mday << " " + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_hour << ":" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_min << ":" + << std::dec << std::setw(2) << std::setfill('0') << its_time.tm_sec << "." << std::dec << std::setw(6) << std::setfill('0') << its_ms << " [" << its_level << "] " << buffer_.data_.str() @@ -138,9 +184,13 @@ message::~message() { } if (its_configuration->has_dlt_log()) { #ifdef USE_DLT +#ifndef ANDROID its_logger->log(level_, buffer_.data_.str().c_str()); +#endif #endif // USE_DLT } +} catch (const std::exception& e) { + std::cout << "\nVSIP: Error destroying message class: " << e.what() << '\n'; } std::streambuf::int_type diff --git a/implementation/message/include/deserializer.hpp b/implementation/message/include/deserializer.hpp index 058fe94..098698d 100644 --- a/implementation/message/include/deserializer.hpp +++ b/implementation/message/include/deserializer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -24,6 +24,7 @@ public: VSOMEIP_EXPORT virtual ~deserializer(); VSOMEIP_EXPORT void set_data(const byte_t *_data, std::size_t _length); + VSOMEIP_EXPORT void set_data(const std::vector &_data); VSOMEIP_EXPORT void append_data(const byte_t *_data, std::size_t _length); VSOMEIP_EXPORT void drop_data(std::size_t _length); diff --git a/implementation/message/include/message_base_impl.hpp b/implementation/message/include/message_base_impl.hpp index 216656b..acad2e8 100644 --- a/implementation/message/include/message_base_impl.hpp +++ b/implementation/message/include/message_base_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/message/include/message_header_impl.hpp b/implementation/message/include/message_header_impl.hpp index b6e305a..f82775f 100644 --- a/implementation/message/include/message_header_impl.hpp +++ b/implementation/message/include/message_header_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/message/include/message_impl.hpp b/implementation/message/include/message_impl.hpp index b121c46..e04d4a7 100644 --- a/implementation/message/include/message_impl.hpp +++ b/implementation/message/include/message_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -47,16 +47,20 @@ public: VSOMEIP_EXPORT bool is_valid_crc() const; VSOMEIP_EXPORT uid_t get_uid() const; - VSOMEIP_EXPORT void set_uid(uid_t _uid); VSOMEIP_EXPORT gid_t get_gid() const; - VSOMEIP_EXPORT void set_gid(gid_t _gid); + + VSOMEIP_EXPORT vsomeip_sec_client_t get_sec_client() const; + VSOMEIP_EXPORT void set_sec_client(const vsomeip_sec_client_t &_sec_client); + + VSOMEIP_EXPORT std::string get_env() const; + VSOMEIP_EXPORT void set_env(const std::string &_env); protected: // members std::shared_ptr< payload > payload_; uint8_t check_result_; - uid_t uid_; - gid_t gid_; + vsomeip_sec_client_t sec_client_; + std::string env_; }; } // namespace vsomeip_v3 diff --git a/implementation/message/include/payload_impl.hpp b/implementation/message/include/payload_impl.hpp index 8ea256c..d77eaa0 100644 --- a/implementation/message/include/payload_impl.hpp +++ b/implementation/message/include/payload_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/message/include/serializer.hpp b/implementation/message/include/serializer.hpp index ff99679..bd626ab 100644 --- a/implementation/message/include/serializer.hpp +++ b/implementation/message/include/serializer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -40,9 +40,16 @@ public: virtual void show(); #endif private: +#ifdef _WIN32 +#pragma warning(push) +#pragma warning(disable : 4251) +#endif std::vector data_; std::uint32_t shrink_count_; std::uint32_t buffer_shrink_threshold_; +#ifdef _WIN32 +#pragma warning(pop) +#endif }; } // namespace vsomeip_v3 diff --git a/implementation/message/src/deserializer.cpp b/implementation/message/src/deserializer.cpp index 0e33faa..cff4596 100644 --- a/implementation/message/src/deserializer.cpp +++ b/implementation/message/src/deserializer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -164,17 +164,18 @@ bool deserializer::look_ahead(std::size_t _index, uint32_t &_value) const { return true; } -message_impl * deserializer::deserialize_message() { - message_impl* deserialized_message = new message_impl; - if (0 != deserialized_message) { - if (false == deserialized_message->deserialize(this)) { - VSOMEIP_ERROR << "SOME/IP message deserialization failed!"; - delete deserialized_message; - deserialized_message = nullptr; - } +message_impl * deserializer::deserialize_message() try { + std::unique_ptr deserialized_message{new message_impl}; + if (false == deserialized_message->deserialize(this)) { + VSOMEIP_ERROR << "SOME/IP message deserialization failed!"; + deserialized_message = nullptr; } - return deserialized_message; + return deserialized_message.release(); +} +catch (const std::exception& e) { + VSOMEIP_ERROR << "SOME/IP message deserialization failed with exception: " << e.what(); + return nullptr; } void deserializer::set_data(const byte_t *_data, std::size_t _length) { @@ -189,6 +190,14 @@ void deserializer::set_data(const byte_t *_data, std::size_t _length) { } } +void +deserializer::set_data(const std::vector &_data) { + + data_ = std::move(_data); + position_ = data_.begin(); + remaining_ = data_.size(); +} + void deserializer::append_data(const byte_t *_data, std::size_t _length) { std::vector::difference_type offset = (position_ - data_.begin()); data_.insert(data_.end(), _data, _data + _length); diff --git a/implementation/message/src/message_base_impl.cpp b/implementation/message/src/message_base_impl.cpp index 43295c4..c1d7da7 100644 --- a/implementation/message/src/message_base_impl.cpp +++ b/implementation/message/src/message_base_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/message/src/message_header_impl.cpp b/implementation/message/src/message_header_impl.cpp index 27950e7..40b98c3 100644 --- a/implementation/message/src/message_header_impl.cpp +++ b/implementation/message/src/message_header_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/message/src/message_impl.cpp b/implementation/message/src/message_impl.cpp index 25cf584..c784e52 100644 --- a/implementation/message/src/message_impl.cpp +++ b/implementation/message/src/message_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,7 +19,9 @@ namespace vsomeip_v3 { message_impl::message_impl() : payload_(runtime::get()->create_payload()), - check_result_(0), uid_(ANY_UID), gid_(ANY_GID) { + check_result_(0) { + + sec_client_.client_type = VSOMEIP_CLIENT_INVALID; } message_impl::~message_impl() { @@ -66,19 +68,43 @@ bool message_impl::is_valid_crc() const { } uid_t message_impl::get_uid() const { - return uid_; + + uid_t its_uid(ANY_UID); + + if (sec_client_.client_type == VSOMEIP_CLIENT_UDS) { + its_uid = sec_client_.client.uds_client.user; + } + + return (its_uid); } -void message_impl::set_uid(uid_t _uid) { - uid_ = _uid; +gid_t message_impl::get_gid() const { + + gid_t its_gid(ANY_GID); + + if (sec_client_.client_type == VSOMEIP_CLIENT_UDS) { + its_gid = sec_client_.client.uds_client.group; + } + + return (its_gid); +} + +vsomeip_sec_client_t message_impl::get_sec_client() const { + + return (sec_client_); +} + +void message_impl::set_sec_client(const vsomeip_sec_client_t &_sec_client) { + + sec_client_ = _sec_client; } -uid_t message_impl::get_gid() const { - return gid_; +std::string message_impl::get_env() const { + return env_; } -void message_impl::set_gid(gid_t _gid) { - gid_ = _gid; +void message_impl::set_env(const std::string &_env) { + env_ = _env; } } // namespace vsomeip_v3 diff --git a/implementation/message/src/payload_impl.cpp b/implementation/message/src/payload_impl.cpp index dd1a6aa..7617cdc 100644 --- a/implementation/message/src/payload_impl.cpp +++ b/implementation/message/src/payload_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/message/src/serializer.cpp b/implementation/message/src/serializer.cpp index fe5196e..fa94a9c 100644 --- a/implementation/message/src/serializer.cpp +++ b/implementation/message/src/serializer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/plugin/include/plugin_manager.hpp b/implementation/plugin/include/plugin_manager.hpp index 61662b8..d398e24 100644 --- a/implementation/plugin/include/plugin_manager.hpp +++ b/implementation/plugin/include/plugin_manager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,8 +19,10 @@ public: VSOMEIP_EXPORT virtual ~plugin_manager() {}; VSOMEIP_EXPORT static std::shared_ptr get(); VSOMEIP_EXPORT virtual void load_plugins() = 0; - VSOMEIP_EXPORT virtual std::shared_ptr get_plugin(plugin_type_e _type, std::string _name) = 0; - + VSOMEIP_EXPORT virtual std::shared_ptr get_plugin(plugin_type_e _type, const std::string &_name) = 0; + VSOMEIP_EXPORT virtual void * load_library(const std::string &_path) = 0; + VSOMEIP_EXPORT virtual void * load_symbol(void * _handle, const std::string &_symbol) = 0; + VSOMEIP_EXPORT virtual void unload_library(void * _handle) = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/plugin/include/plugin_manager_impl.hpp b/implementation/plugin/include/plugin_manager_impl.hpp index eb7d09f..e88772e 100644 --- a/implementation/plugin/include/plugin_manager_impl.hpp +++ b/implementation/plugin/include/plugin_manager_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -29,7 +29,8 @@ public: VSOMEIP_EXPORT void load_plugins(); - VSOMEIP_EXPORT std::shared_ptr get_plugin(plugin_type_e _type, std::string _name); + VSOMEIP_EXPORT std::shared_ptr get_plugin(plugin_type_e _type, + const std::string &_name); VSOMEIP_EXPORT std::shared_ptr load_plugin( const std::string& _library, plugin_type_e _type, @@ -37,12 +38,13 @@ public: VSOMEIP_EXPORT bool unload_plugin(plugin_type_e _type); + VSOMEIP_EXPORT void * load_library(const std::string &_path); + VSOMEIP_EXPORT void * load_symbol(void * _handle, const std::string &_symbol); + VSOMEIP_EXPORT void unload_library(void * _handle); + private: void add_plugin(const std::shared_ptr &_plugin, const std::string& _name); - void * load_library(const std::string &_path); - void * load_symbol(void * _handle, const std::string &_symbol); - bool plugins_loaded_; std::mutex loader_mutex_; diff --git a/implementation/plugin/src/plugin_manager.cpp b/implementation/plugin/src/plugin_manager.cpp index f8ddaa1..d64cbaa 100644 --- a/implementation/plugin/src/plugin_manager.cpp +++ b/implementation/plugin/src/plugin_manager.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/plugin/src/plugin_manager_impl.cpp b/implementation/plugin/src/plugin_manager_impl.cpp index 159eea9..bfaf272 100644 --- a/implementation/plugin/src/plugin_manager_impl.cpp +++ b/implementation/plugin/src/plugin_manager_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,6 +6,7 @@ #include #include #include +#include #include #ifdef _WIN32 @@ -110,7 +111,8 @@ void plugin_manager_impl::load_plugins() { } } -std::shared_ptr plugin_manager_impl::get_plugin(plugin_type_e _type, std::string _name) { +std::shared_ptr plugin_manager_impl::get_plugin(plugin_type_e _type, + const std::string &_name) { std::lock_guard its_lock_start_stop(plugins_mutex_); auto its_type = plugins_.find(_type); if (its_type != plugins_.end()) { @@ -180,38 +182,52 @@ void * plugin_manager_impl::load_library(const std::string &_path) { #endif } -void * plugin_manager_impl::load_symbol(void * _handle, - const std::string &_symbol) { - void * its_symbol = 0; +void * plugin_manager_impl::load_symbol(void * _handle, const std::string &_symbol_name) { + void* symbol = nullptr; + if (_handle) { #ifdef _WIN32 - HINSTANCE hDLL = (HINSTANCE)_handle; - if (hDLL != NULL) { + symbol = GetProcAddress(reinterpret_cast(_handle), _symbol_name.c_str()); +#else + symbol = dlsym(_handle, _symbol_name.c_str()); +#endif - typedef UINT(CALLBACK* LPFNDLLFUNC1)(DWORD, UINT); + if (!symbol) { + char* error_message = nullptr; - LPFNDLLFUNC1 lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL, _symbol.c_str()); - if (!lpfnDllFunc1) { - FreeLibrary(hDLL); - std::cerr << "Loading symbol \"" << _symbol << "\" failed (" << GetLastError() << ")" << std::endl; - } - else { - its_symbol = lpfnDllFunc1; - } - } +#ifdef _WIN32 + DWORD error_code = GetLastError(); + FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + error_code, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + reinterpret_cast(&error_message), + 0, + nullptr + ); #else - if (0 != _handle) { - dlerror(); // Clear previous error - its_symbol = dlsym(_handle, _symbol.c_str()); - const char *dlsym_error = dlerror(); - if (dlsym_error) { - VSOMEIP_INFO << "Cannot load symbol : " << _symbol << " : " << dlsym_error; - dlclose(_handle); + error_message = dlerror(); +#endif + + VSOMEIP_ERROR << "Cannot load symbol " << std::quoted(_symbol_name) << " because: " << error_message; + +#ifdef _WIN32 + // Required to release memory allocated by FormatMessageA() + LocalFree(error_message); +#endif } - } else { - VSOMEIP_ERROR << "Loading failed: (" << dlerror() << ")"; } + return symbol; +} + +void plugin_manager_impl::unload_library(void * _handle) { + if (_handle) { +#ifdef _WIN32 + FreeLibrary(reinterpret_cast(_handle)); +#else + dlclose(_handle); #endif - return (its_symbol); + } } } // namespace vsomeip_v3 diff --git a/implementation/protocol/include/assign_client_ack_command.hpp b/implementation/protocol/include/assign_client_ack_command.hpp new file mode 100644 index 0000000..ec11268 --- /dev/null +++ b/implementation/protocol/include/assign_client_ack_command.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_ASSIGN_CLIENT_ACK_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_ASSIGN_CLIENT_ACK_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class assign_client_ack_command + : public command { +public: + assign_client_ack_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + client_t get_assigned() const; + void set_assigned(client_t _assigned); + +private: + client_t assigned_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_ASSIGN_CLIENT_ACK_COMMAND_HPP_ diff --git a/implementation/protocol/include/assign_client_command.hpp b/implementation/protocol/include/assign_client_command.hpp new file mode 100644 index 0000000..b1932da --- /dev/null +++ b/implementation/protocol/include/assign_client_command.hpp @@ -0,0 +1,38 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_ASSIGN_CLIENT_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_ASSIGN_CLIENT_COMMAND_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class assign_client_command + : public command { +public: + assign_client_command(); + + // command + id_e get_id() const; + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + std::string get_name() const; + void set_name(const std::string &_name); + +private: + std::string name_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_ASSIGN_CLIENT_COMMAND_HPP_ diff --git a/implementation/protocol/include/command.hpp b/implementation/protocol/include/command.hpp new file mode 100644 index 0000000..a39990a --- /dev/null +++ b/implementation/protocol/include/command.hpp @@ -0,0 +1,46 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_COMMAND_HPP_ + +#include // memcpy +#include + +#include + +#include "protocol.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +using commandize_t = std::uint32_t; + +class command { +public: + inline id_e get_id() const { return id_; } + inline version_t get_version() const { return version_; } + inline client_t get_client() const { return client_; } + inline void set_client(client_t _client) { client_ = _client; } + inline command_size_t get_size() const { return size_; } + + virtual void serialize(std::vector &_buffer, + error_e &_error) const; + virtual void deserialize(const std::vector &_buffer, + error_e &_error); + +protected: + id_e id_; + version_t version_; + client_t client_; + mutable command_size_t size_; + + command(id_e _id); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_COMMAND_HPP_ diff --git a/implementation/protocol/include/deregister_application_command.hpp b/implementation/protocol/include/deregister_application_command.hpp new file mode 100644 index 0000000..9b1bcb8 --- /dev/null +++ b/implementation/protocol/include/deregister_application_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_DEREGISTER_APPLICATION_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_DEREGISTER_APPLICATION_COMMAND_HPP_ + +#include "simple_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class deregister_application_command + : public simple_command { + +public: + deregister_application_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_DEREGISTER_APPLICATION_COMMAND_HPP_ diff --git a/implementation/protocol/include/distribute_security_policies_command.hpp b/implementation/protocol/include/distribute_security_policies_command.hpp new file mode 100644 index 0000000..2b2c673 --- /dev/null +++ b/implementation/protocol/include/distribute_security_policies_command.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_DISTRIBUTE_SECURITY_POLICIES_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_DISTRIBUTE_SECURITY_POLICIES_COMMAND_HPP_ + +#include +#include +#include +#include + +#include "command.hpp" + +namespace vsomeip_v3 { + +class payload; +struct policy; + +namespace protocol { + +class distribute_security_policies_command + : public command { +public: + distribute_security_policies_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + std::set > get_policies() const; + + void set_payloads(const std::map > &_payloads); + +private: + std::set > policies_; + std::vector payload_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_DISTRIBUTE_SECURITY_POLICIES_COMMAND_HPP_ diff --git a/implementation/protocol/include/dummy_command.hpp b/implementation/protocol/include/dummy_command.hpp new file mode 100644 index 0000000..70f4f6c --- /dev/null +++ b/implementation/protocol/include/dummy_command.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_DUMMY_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_DUMMY_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class dummy_command + : public command { +public: + dummy_command(); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_DUMMY_COMMAND_HPP_ diff --git a/implementation/protocol/include/expire_command.hpp b/implementation/protocol/include/expire_command.hpp new file mode 100644 index 0000000..4c47aa9 --- /dev/null +++ b/implementation/protocol/include/expire_command.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_EXPIRE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_EXPIRE_COMMAND_HPP_ + +#include + +#include + +#include "subscribe_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class expire_command + : public subscribe_command_base { + +public: + expire_command(); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_EXPIRE_COMMAND_HPP_ diff --git a/implementation/protocol/include/multiple_services_command_base.hpp b/implementation/protocol/include/multiple_services_command_base.hpp new file mode 100644 index 0000000..d679b16 --- /dev/null +++ b/implementation/protocol/include/multiple_services_command_base.hpp @@ -0,0 +1,37 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_MULTIPLE_SERVICES_COMMAND_BASE_HPP_ +#define VSOMEIP_V3_PROTOCOL_MULTIPLE_SERVICES_COMMAND_BASE_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class multiple_services_command_base + : public command { +public: + multiple_services_command_base(id_e _id); + + // command + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + std::set get_services() const; + void set_services(const std::set &_services); + void add_service(const service &_service); + +private: + std::set services_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_MULTIPLE_SERVICES_COMMAND_BASE_HPP_ diff --git a/implementation/protocol/include/offer_service_command.hpp b/implementation/protocol/include/offer_service_command.hpp new file mode 100644 index 0000000..22e5f36 --- /dev/null +++ b/implementation/protocol/include/offer_service_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_OFFER_SERVICE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_OFFER_SERVICE_COMMAND_HPP_ + +#include "service_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class offer_service_command + : public service_command_base { + +public: + offer_service_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_OFFER_SERVICE_COMMAND_HPP_ diff --git a/implementation/protocol/include/offered_services_request_command.hpp b/implementation/protocol/include/offered_services_request_command.hpp new file mode 100644 index 0000000..3ced949 --- /dev/null +++ b/implementation/protocol/include/offered_services_request_command.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_OFFERED_SERVICES_REQUEST_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_OFFERED_SERVICES_REQUEST_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class offered_services_request_command + : public command { + +public: + offered_services_request_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + offer_type_e get_offer_type() const; + void set_offer_type(offer_type_e _offer_type); + +private: + offer_type_e offer_type_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_OFFERED_SERVICES_REQUEST_COMMAND_HPP_ diff --git a/implementation/protocol/include/offered_services_response_command.hpp b/implementation/protocol/include/offered_services_response_command.hpp new file mode 100644 index 0000000..79a8f2c --- /dev/null +++ b/implementation/protocol/include/offered_services_response_command.hpp @@ -0,0 +1,23 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_OFFERED_SERVICES_RESPONSE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_OFFERED_SERVICES_RESPONSE_COMMAND_HPP_ + +#include "multiple_services_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class offered_services_response_command + : public multiple_services_command_base { +public: + offered_services_response_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_OFFERED_SERVICES_RESPONSE_COMMAND_HPP_ diff --git a/implementation/protocol/include/ping_command.hpp b/implementation/protocol/include/ping_command.hpp new file mode 100644 index 0000000..369e255 --- /dev/null +++ b/implementation/protocol/include/ping_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_PING_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_PING_COMMAND_HPP_ + +#include "simple_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class ping_command + : public simple_command { + +public: + ping_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_PING_COMMAND_HPP_ diff --git a/implementation/protocol/include/pong_command.hpp b/implementation/protocol/include/pong_command.hpp new file mode 100644 index 0000000..1876f0d --- /dev/null +++ b/implementation/protocol/include/pong_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_PONG_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_PONG_COMMAND_HPP_ + +#include "simple_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class pong_command + : public simple_command { + +public: + pong_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_PONG_COMMAND_HPP_ diff --git a/implementation/protocol/include/protocol.hpp b/implementation/protocol/include/protocol.hpp new file mode 100644 index 0000000..08a770b --- /dev/null +++ b/implementation/protocol/include/protocol.hpp @@ -0,0 +1,142 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_PROTOCOL_HPP_ +#define VSOMEIP_V3_PROTOCOL_PROTOCOL_HPP_ + +#include +#include + +namespace vsomeip_v3 { +namespace protocol { + +using version_t = std::uint16_t; +using command_size_t = std::uint32_t; + +enum class id_e : uint8_t { + ASSIGN_CLIENT_ID = 0x00, + ASSIGN_CLIENT_ACK_ID = 0x01, + REGISTER_APPLICATION_ID = 0x02, + DEREGISTER_APPLICATION_ID = 0x03, + // APPLICATION_LOST_ID = 0x04, + ROUTING_INFO_ID = 0x05, + REGISTERED_ACK_ID = 0x06, + PING_ID = 0x07, + PONG_ID = 0x08, + OFFER_SERVICE_ID = 0x10, + STOP_OFFER_SERVICE_ID = 0x11, + SUBSCRIBE_ID = 0x12, + UNSUBSCRIBE_ID = 0x13, + REQUEST_SERVICE_ID = 0x14, + RELEASE_SERVICE_ID = 0x15, + SUBSCRIBE_NACK_ID = 0x16, + SUBSCRIBE_ACK_ID = 0x17, + SEND_ID = 0x18, + NOTIFY_ID = 0x19, + NOTIFY_ONE_ID = 0x1A, + REGISTER_EVENT_ID = 0x1B, + UNREGISTER_EVENT_ID = 0x1C, + ID_RESPONSE_ID = 0x1D, + ID_REQUEST_ID = 0x1E, + OFFERED_SERVICES_REQUEST_ID = 0x1F, + OFFERED_SERVICES_RESPONSE_ID = 0x20, + UNSUBSCRIBE_ACK_ID = 0x21, + RESEND_PROVIDED_EVENTS_ID = 0x22, + UPDATE_SECURITY_POLICY_ID = 0x23, + UPDATE_SECURITY_POLICY_RESPONSE_ID = 0x24, + REMOVE_SECURITY_POLICY_ID = 0x25, + REMOVE_SECURITY_POLICY_RESPONSE_ID = 0x26, + UPDATE_SECURITY_CREDENTIALS_ID = 0x27, + DISTRIBUTE_SECURITY_POLICIES_ID = 0x28, + UPDATE_SECURITY_POLICY_INT_ID = 0x29, + EXPIRE_ID = 0x2A, + SUSPEND_ID = 0x30, + UNKNOWN_ID = 0xFF +}; + +enum class error_e : uint8_t { + ERROR_OK = 0x00, + ERROR_NOT_ENOUGH_BYTES = 0x01, + ERROR_MAX_COMMAND_SIZE_EXCEEDED = 0x02, + ERROR_MISMATCH = 0x04, + ERROR_MALFORMED = 0x08, + ERROR_NOT_ALLOWED = 0x10, + ERROR_UNKNOWN = 0xff +}; + +enum class routing_info_entry_type_e : std::uint8_t { + RIE_ADD_CLIENT = 0x00, + RIE_DELETE_CLIENT = 0x01, + RIE_ADD_SERVICE_INSTANCE = 0x02, + RIE_DELETE_SERVICE_INSTANCE = 0x04, + RIE_UNKNOWN = 0xff +}; + +using pending_id_t = std::uint16_t; + +struct service { + service_t service_; + instance_t instance_; + major_version_t major_; + minor_version_t minor_; + + service() + : service_(ANY_SERVICE), + instance_(ANY_INSTANCE), + major_(ANY_MAJOR), + minor_(ANY_MINOR) { + } + + service(service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) + : service_(_service), + instance_(_instance), + major_(_major), + minor_(_minor) { + } + + bool operator<(const service &_other) const { + + return (service_ < _other.service_ + || (service_ == _other.service_ + && instance_ < _other.instance_)); + } +}; + +static const version_t MAX_SUPPORTED_VERSION = 0; + +static const size_t TAG_SIZE = 4; +static const size_t COMMAND_HEADER_SIZE = 9; +static const size_t SEND_COMMAND_HEADER_SIZE = 15; +static const size_t ROUTING_INFO_ENTRY_HEADER_SIZE = 7; + +static const size_t COMMAND_POSITION_ID = 0; +static const size_t COMMAND_POSITION_VERSION = 1; +static const size_t COMMAND_POSITION_CLIENT = 3; +static const size_t COMMAND_POSITION_SIZE = 5; +static const size_t COMMAND_POSITION_PAYLOAD = 9; + +static inline id_e get_command(byte_t _byte) { + + id_e its_id(id_e::UNKNOWN_ID); + if (_byte <= static_cast(id_e::SUSPEND_ID)) + its_id = static_cast(_byte); + return (its_id); +} + +static inline bool operator==(const byte_t &_lhs, const id_e &_rhs) { + + return (_lhs == static_cast(_rhs)); +} + +static inline bool operator==(const id_e &_lhs, const byte_t &_rhs) { + + return (_rhs == _lhs); +} + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_PROTOCOL_HPP_ diff --git a/implementation/protocol/include/register_application_command.hpp b/implementation/protocol/include/register_application_command.hpp new file mode 100644 index 0000000..ffb15ad --- /dev/null +++ b/implementation/protocol/include/register_application_command.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_REGISTER_APPLICATION_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_REGISTER_APPLICATION_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class register_application_command + : public command { + +public: + register_application_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + port_t get_port() const; + void set_port(port_t _port); + +private: + port_t port_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REGISTER_APPLICATION_COMMAND_HPP_ diff --git a/implementation/protocol/include/register_event.hpp b/implementation/protocol/include/register_event.hpp new file mode 100644 index 0000000..f468c02 --- /dev/null +++ b/implementation/protocol/include/register_event.hpp @@ -0,0 +1,67 @@ +#ifndef VSOMEIP_V3_PROTOCOL_REGISTER_EVENT_HPP_ +#define VSOMEIP_V3_PROTOCOL_REGISTER_EVENT_HPP_ + +#include +#include +#include +#include + +#include "protocol.hpp" +#include +#include + +namespace vsomeip_v3 { +namespace protocol { + +class register_event { +public: + register_event(service_t service = ANY_SERVICE, instance_t instance = ANY_INSTANCE, + event_t event = ANY_EVENT, event_type_e event_type = event_type_e::ET_UNKNOWN, + bool is_provided = false, reliability_type_e reliability = reliability_type_e::RT_UNKNOWN, + bool is_cyclic = false, uint16_t num_eventg = 0, + const std::set &eventgroups = std::set()); + void serialize(std::vector &_buffer, size_t &_offset) const; + void deserialize(const std::vector &_buffer, size_t &_offset); + + service_t get_service() const { return service_; } + void set_service(service_t _service) { service_ = _service; } + + instance_t get_instance() const { return instance_; } + void set_instance(instance_t _instance) { instance_ = _instance; } + + event_t get_event() const { return event_; } + void set_event(event_t _event) { event_ = _event; } + + event_type_e get_event_type() const { return event_type_; } + void set_event_type(event_type_e _event_type) { event_type_ = _event_type; } + + bool is_provided() const { return is_provided_; } + void set_provided(bool _is_provided) { is_provided_ = _is_provided; } + + reliability_type_e get_reliability() const { return reliability_; } + void set_reliability(reliability_type_e _reliability) { reliability_ = _reliability; } + + bool is_cyclic() const { return is_cyclic_; } + void set_cyclic(bool _cyclic) { is_cyclic_ = _cyclic; } + + uint16_t get_num_eventgroups() const { return num_eventg_; } + + std::set get_eventgroups() const { return eventgroups_; } + void set_eventgroups(const std::set &_eventgroups); + +private: + service_t service_; + instance_t instance_; + event_t event_; + event_type_e event_type_; + bool is_provided_; + reliability_type_e reliability_; + bool is_cyclic_; + uint16_t num_eventg_; + std::set eventgroups_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REGISTER_EVENT_HPP_ diff --git a/implementation/protocol/include/register_events_command.hpp b/implementation/protocol/include/register_events_command.hpp new file mode 100644 index 0000000..23dd7fa --- /dev/null +++ b/implementation/protocol/include/register_events_command.hpp @@ -0,0 +1,40 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_REGISTER_EVENTS_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_REGISTER_EVENTS_COMMAND_HPP_ + +#include + +#include + +#include "command.hpp" +#include "register_event.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class register_events_command + : public command { +public: + + register_events_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + std::size_t get_num_registrations() const; + + bool add_registration(const register_event &_register_event); + bool get_registration_at(std::size_t _position, register_event & _reg) const; + +private: + std::vector registrations_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REGISTER_EVENTS_COMMAND_HPP_ diff --git a/implementation/protocol/include/registered_ack_command.hpp b/implementation/protocol/include/registered_ack_command.hpp new file mode 100644 index 0000000..0ae85ba --- /dev/null +++ b/implementation/protocol/include/registered_ack_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_REGISTERED_ACK_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_REGISTERED_ACK_COMMAND_HPP_ + +#include "simple_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class registered_ack_command + : public simple_command { + +public: + registered_ack_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REGISTERED_ACK_COMMAND_HPP_ diff --git a/implementation/protocol/include/release_service_command.hpp b/implementation/protocol/include/release_service_command.hpp new file mode 100644 index 0000000..537fd14 --- /dev/null +++ b/implementation/protocol/include/release_service_command.hpp @@ -0,0 +1,39 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_RELEASE_SERVICE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_RELEASE_SERVICE_COMMAND_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class release_service_command + : public command { +public: + release_service_command(); + + // command + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + service_t get_service() const; + void set_service(service_t _service); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + +private: + service service_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_RELEASE_SERVICE_COMMAND_HPP_ diff --git a/implementation/protocol/include/remove_security_policy_command.hpp b/implementation/protocol/include/remove_security_policy_command.hpp new file mode 100644 index 0000000..83480e4 --- /dev/null +++ b/implementation/protocol/include/remove_security_policy_command.hpp @@ -0,0 +1,41 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_REMOVE_SECURITY_POLICY_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_REMOVE_SECURITY_POLICY_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class remove_security_policy_command + : public command { +public: + remove_security_policy_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + uint32_t get_update_id() const; + void set_update_id(uint32_t _update_id); + + uid_t get_uid() const; + void set_uid(uid_t _uid); + + gid_t get_gid() const; + void set_gid(gid_t _gid); + +private: + uint32_t update_id_; + uid_t uid_; + gid_t gid_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REMOVE_SECURITY_POLICY_COMMAND_HPP_ diff --git a/implementation/protocol/include/remove_security_policy_response_command.hpp b/implementation/protocol/include/remove_security_policy_response_command.hpp new file mode 100644 index 0000000..7deda2c --- /dev/null +++ b/implementation/protocol/include/remove_security_policy_response_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_HPP_ + +#include "security_policy_response_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class remove_security_policy_response_command + : public security_policy_response_command_base { + +public: + remove_security_policy_response_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_HPP_ diff --git a/implementation/protocol/include/request_service_command.hpp b/implementation/protocol/include/request_service_command.hpp new file mode 100644 index 0000000..945247e --- /dev/null +++ b/implementation/protocol/include/request_service_command.hpp @@ -0,0 +1,23 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_REQUEST_SERVICE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_REQUEST_SERVICE_COMMAND_HPP_ + +#include "multiple_services_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class request_service_command + : public multiple_services_command_base { +public: + request_service_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REQUEST_SERVICE_COMMAND_HPP_ diff --git a/implementation/protocol/include/resend_provided_events_command.hpp b/implementation/protocol/include/resend_provided_events_command.hpp new file mode 100644 index 0000000..1fc493c --- /dev/null +++ b/implementation/protocol/include/resend_provided_events_command.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_RESEND_PROVIDED_EVENTS_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_RESEND_PROVIDED_EVENTS_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class resend_provided_events_command + : public command { +public: + resend_provided_events_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + pending_remote_offer_id_t get_remote_offer_id() const; + void set_remote_offer_id(pending_remote_offer_id_t _remote_offer_id); + +private: + pending_remote_offer_id_t remote_offer_id_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_RESEND_PROVIDED_EVENTS_COMMAND_HPP_ diff --git a/implementation/protocol/include/routing_info_command.hpp b/implementation/protocol/include/routing_info_command.hpp new file mode 100644 index 0000000..2cb0ab7 --- /dev/null +++ b/implementation/protocol/include/routing_info_command.hpp @@ -0,0 +1,36 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_ROUTING_INFO_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_ROUTING_INFO_COMMAND_HPP_ + +#include "command.hpp" +#include "routing_info_entry.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class routing_info_command + : public command { +public: + routing_info_command(); + + // command + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + const std::vector &get_entries() const; + void set_entries(std::vector &&_entries); + void add_entry(const routing_info_entry &_entry); + +private: + std::vector entries_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_ROUTING_INFO_COMMAND_HPP_ diff --git a/implementation/protocol/include/routing_info_entry.hpp b/implementation/protocol/include/routing_info_entry.hpp new file mode 100644 index 0000000..b27190b --- /dev/null +++ b/implementation/protocol/include/routing_info_entry.hpp @@ -0,0 +1,59 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_ROUTING_INFO_ENTRY_HPP_ +#define VSOMEIP_V3_PROTOCOL_ROUTING_INFO_ENTRY_HPP_ + +#include + +#include + +#include "protocol.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class routing_info_entry { +public: + routing_info_entry(); + routing_info_entry(const routing_info_entry &_source); + + void serialize(std::vector &_buffer, size_t &_index, + error_e &_error) const; + void deserialize(const std::vector &_buffer, size_t &_index, + error_e &_error); + + routing_info_entry_type_e get_type() const; + void set_type(routing_info_entry_type_e _type); + + size_t get_size() const; + + client_t get_client() const; + void set_client(client_t _client); + + boost::asio::ip::address get_address() const; + void set_address(const boost::asio::ip::address &_address); + + port_t get_port() const; + void set_port(port_t _port); + + const std::vector &get_services() const; + void add_service(const service &_service); + +private: + routing_info_entry_type_e type_; + + client_t client_; + + boost::asio::ip::address address_; + port_t port_; + + std::vector services_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_ROUTING_INFO_ENTRY_HPP_ diff --git a/implementation/protocol/include/security_policy_response_command_base.hpp b/implementation/protocol/include/security_policy_response_command_base.hpp new file mode 100644 index 0000000..799f703 --- /dev/null +++ b/implementation/protocol/include/security_policy_response_command_base.hpp @@ -0,0 +1,38 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SECURITY_POLICY_RESPONSE_COMMAND_BASE_HPP_ +#define VSOMEIP_V3_PROTOCOL_SECURITY_POLICY_RESPONSE_COMMAND_BASE_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { + +struct policy; + +namespace protocol { + +class security_policy_response_command_base + : public command { +public: + security_policy_response_command_base(id_e _id); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + uint32_t get_update_id() const; + void set_update_id(uint32_t _update_id); + +private: + uint32_t update_id_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SECURITY_POLICY_RESPONSE_COMMAND_BASE_HPP_ diff --git a/implementation/protocol/include/send_command.hpp b/implementation/protocol/include/send_command.hpp new file mode 100644 index 0000000..cb10b45 --- /dev/null +++ b/implementation/protocol/include/send_command.hpp @@ -0,0 +1,52 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SEND_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_SEND_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class send_command + : public command { +public: + send_command(id_e _id); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + + bool is_reliable() const; + void set_reliable(bool _is_reliable); + + uint8_t get_status() const; + void set_status(uint8_t _status); + + client_t get_target() const; + void set_target(client_t _target); + + // TODO: Optimize this as the vector might be huge! + std::vector get_message() const; + void set_message(const std::vector &_message); + +private: + + instance_t instance_; + bool is_reliable_; + uint8_t status_; // TODO: DO WE REALLY NEED THIS? + client_t target_; + std::vector message_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_BASIC_COMMAND_HPP_ diff --git a/implementation/protocol/include/service_command_base.hpp b/implementation/protocol/include/service_command_base.hpp new file mode 100644 index 0000000..05b488d --- /dev/null +++ b/implementation/protocol/include/service_command_base.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SERVICE_COMMAND_BASE_HPP_ +#define VSOMEIP_V3_PROTOCOL_SERVICE_COMMAND_BASE_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class service_command_base + : public command { + +public: + service_t get_service() const; + void set_service(service_t _service); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + + major_version_t get_major() const; + void set_major(major_version_t _major); + + minor_version_t get_minor() const; + void set_minor(minor_version_t _minor); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + +protected: + service_command_base(id_e _id); + +private: + service service_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SERVICE_COMMAND_BASE_HPP_ diff --git a/implementation/protocol/include/simple_command.hpp b/implementation/protocol/include/simple_command.hpp new file mode 100644 index 0000000..09ae8fd --- /dev/null +++ b/implementation/protocol/include/simple_command.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SIMPLE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_SIMPLE_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class simple_command + : public command { +public: + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + +protected: + simple_command(id_e _id); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SIMPLE_COMMAND_HPP_ diff --git a/implementation/protocol/include/stop_offer_service_command.hpp b/implementation/protocol/include/stop_offer_service_command.hpp new file mode 100644 index 0000000..a9a51d2 --- /dev/null +++ b/implementation/protocol/include/stop_offer_service_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_STOP_OFFER_SERVICE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_STOP_OFFER_SERVICE_COMMAND_HPP_ + +#include "service_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class stop_offer_service_command + : public service_command_base { + +public: + stop_offer_service_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_STOP_OFFER_SERVICE_COMMAND_HPP_ diff --git a/implementation/protocol/include/subscribe_ack_command.hpp b/implementation/protocol/include/subscribe_ack_command.hpp new file mode 100644 index 0000000..b3f4c76 --- /dev/null +++ b/implementation/protocol/include/subscribe_ack_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SUBSCRIBE_ACK_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_SUBSCRIBE_ACK_COMMAND_HPP_ + +#include "subscribe_ack_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class subscribe_ack_command + : public subscribe_ack_command_base { + +public: + subscribe_ack_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SUBSCRIBE_ACK_COMMAND_HPP_ diff --git a/implementation/protocol/include/subscribe_ack_command_base.hpp b/implementation/protocol/include/subscribe_ack_command_base.hpp new file mode 100644 index 0000000..3a738b9 --- /dev/null +++ b/implementation/protocol/include/subscribe_ack_command_base.hpp @@ -0,0 +1,57 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SUBSCRIBE_ACK_COMMAND_BASE_HPP_ +#define VSOMEIP_V3_PROTOCOL_SUBSCRIBE_ACK_COMMAND_BASE_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class subscribe_ack_command_base + : public command { + +public: + service_t get_service() const; + void set_service(service_t _service); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + + eventgroup_t get_eventgroup() const; + void set_eventgroup(eventgroup_t _eventgroup); + + client_t get_subscriber() const; + void set_subscriber(client_t _subscriber); + + event_t get_event() const; + void set_event(event_t _event); + + pending_id_t get_pending_id() const; + void set_pending_id(pending_id_t _pending_id); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + +protected: + subscribe_ack_command_base(id_e _id); + + service_t service_; + instance_t instance_; + eventgroup_t eventgroup_; + client_t subscriber_; + event_t event_; + pending_id_t pending_id_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SUBSCRIBE_ACK_COMMAND_BASE_HPP_ diff --git a/implementation/protocol/include/subscribe_command.hpp b/implementation/protocol/include/subscribe_command.hpp new file mode 100644 index 0000000..d552562 --- /dev/null +++ b/implementation/protocol/include/subscribe_command.hpp @@ -0,0 +1,39 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SUBSCRIBE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_SUBSCRIBE_COMMAND_HPP_ + +#include + +#include + +#include "subscribe_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class subscribe_command + : public subscribe_command_base { + +public: + subscribe_command(); + + std::shared_ptr get_filter() const; + void set_filter(const std::shared_ptr &_filter); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + +private: + std::shared_ptr filter_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SUBSCRIBE_COMMAND_HPP_ diff --git a/implementation/protocol/include/subscribe_command_base.hpp b/implementation/protocol/include/subscribe_command_base.hpp new file mode 100644 index 0000000..a16c2fe --- /dev/null +++ b/implementation/protocol/include/subscribe_command_base.hpp @@ -0,0 +1,59 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SUBSCRIBE_COMMAND_BASE_HPP_ +#define VSOMEIP_V3_PROTOCOL_SUBSCRIBE_COMMAND_BASE_HPP_ + +#include + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class subscribe_command_base + : public command { + +public: + service_t get_service() const; + void set_service(service_t _service); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + + eventgroup_t get_eventgroup() const; + void set_eventgroup(eventgroup_t _eventgroup); + + major_version_t get_major() const; + void set_major(major_version_t _major); + + event_t get_event() const; + void set_event(event_t _event); + + pending_id_t get_pending_id() const; + void set_pending_id(pending_id_t _pending_id); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + +protected: + subscribe_command_base(id_e _id); + + service_t service_; + instance_t instance_; + eventgroup_t eventgroup_; + major_version_t major_; + event_t event_; + pending_id_t pending_id_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SUBSCRIBE_COMMAND_BASE_HPP_ diff --git a/implementation/protocol/include/subscribe_nack_command.hpp b/implementation/protocol/include/subscribe_nack_command.hpp new file mode 100644 index 0000000..5b79ce5 --- /dev/null +++ b/implementation/protocol/include/subscribe_nack_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SUBSCRIBE_NACK_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_SUBSCRIBE_NACK_COMMAND_HPP_ + +#include "subscribe_ack_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class subscribe_nack_command + : public subscribe_ack_command_base { + +public: + subscribe_nack_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SUBSCRIBE_NACK_COMMAND_HPP_ diff --git a/implementation/protocol/include/suspend_command.hpp b/implementation/protocol/include/suspend_command.hpp new file mode 100644 index 0000000..414b36f --- /dev/null +++ b/implementation/protocol/include/suspend_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_SUSPEND_HPP_ +#define VSOMEIP_V3_PROTOCOL_SUSPEND_HPP_ + +#include "simple_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class suspend_command + : public simple_command { + +public: + suspend_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_SUSPEND_COMMAND_HPP_ diff --git a/implementation/protocol/include/unregister_event_command.hpp b/implementation/protocol/include/unregister_event_command.hpp new file mode 100644 index 0000000..9779946 --- /dev/null +++ b/implementation/protocol/include/unregister_event_command.hpp @@ -0,0 +1,49 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_UNREGISTER_EVENT_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_UNREGISTER_EVENT_COMMAND_HPP_ + +#include + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class unregister_event_command + : public command { +public: + unregister_event_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + service_t get_service() const; + void set_service(service_t _service); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + + event_t get_event() const; + void set_event(event_t _event); + + bool is_provided() const; + void set_provided(bool _is_provided); + +private: + service_t service_; + instance_t instance_; + event_t event_; + bool is_provided_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_REGISTER_EVENT_COMMAND_HPP_ diff --git a/implementation/protocol/include/unsubscribe_ack_command.hpp b/implementation/protocol/include/unsubscribe_ack_command.hpp new file mode 100644 index 0000000..7afaa1d --- /dev/null +++ b/implementation/protocol/include/unsubscribe_ack_command.hpp @@ -0,0 +1,47 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_UNSUBSCRIBE_ACK_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_UNSUBSCRIBE_ACK_COMMAND_HPP_ + +#include "command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class unsubscribe_ack_command + : public command { + +public: + unsubscribe_ack_command(); + + service_t get_service() const; + void set_service(service_t _service); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + + eventgroup_t get_eventgroup() const; + void set_eventgroup(eventgroup_t _eventgroup); + + pending_id_t get_pending_id() const; + void set_pending_id(pending_id_t _pending_id); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); + +private: + service_t service_; + instance_t instance_; + eventgroup_t eventgroup_; + pending_id_t pending_id_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_UNSUBSCRIBE_ACK_COMMAND_HPP_ diff --git a/implementation/protocol/include/unsubscribe_command.hpp b/implementation/protocol/include/unsubscribe_command.hpp new file mode 100644 index 0000000..e0a05ce --- /dev/null +++ b/implementation/protocol/include/unsubscribe_command.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_UNSUBSCRIBE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_UNSUBSCRIBE_COMMAND_HPP_ + +#include + +#include + +#include "subscribe_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class unsubscribe_command + : public subscribe_command_base { + +public: + unsubscribe_command(); + + void serialize(std::vector &_buffer, + error_e &_error) const; + void deserialize(const std::vector &_buffer, + error_e &_error); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_UNSUBSCRIBE_COMMAND_HPP_ diff --git a/implementation/protocol/include/update_security_credentials_command.hpp b/implementation/protocol/include/update_security_credentials_command.hpp new file mode 100644 index 0000000..37d9c34 --- /dev/null +++ b/implementation/protocol/include/update_security_credentials_command.hpp @@ -0,0 +1,39 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_CREDENTIALS_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_CREDENTIALS_COMMAND_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { + +struct policy; + +namespace protocol { + +class update_security_credentials_command + : public command { +public: + update_security_credentials_command(); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + std::set > get_credentials() const; + void set_credentials( + const std::set > &_credentials); + +private: + std::set > credentials_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_CREDENTIALS_COMMAND_HPP_ diff --git a/implementation/protocol/include/update_security_policy_command.hpp b/implementation/protocol/include/update_security_policy_command.hpp new file mode 100644 index 0000000..9a42d64 --- /dev/null +++ b/implementation/protocol/include/update_security_policy_command.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_POLICY_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_POLICY_COMMAND_HPP_ + +#include + +#include "command.hpp" + +namespace vsomeip_v3 { + +struct policy; + +namespace protocol { + +class update_security_policy_command + : public command { +public: + update_security_policy_command(bool _is_internal = false); + + void serialize(std::vector &_buffer, error_e &_error) const; + void deserialize(const std::vector &_buffer, error_e &_error); + + // specific + uint32_t get_update_id() const; + void set_update_id(uint32_t _update_id); + + std::shared_ptr get_policy() const; + void set_policy(const std::shared_ptr &_policy); + +private: + uint32_t update_id_; + std::shared_ptr policy_; +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_POLICY_COMMAND_HPP_ diff --git a/implementation/protocol/include/update_security_policy_response_command.hpp b/implementation/protocol/include/update_security_policy_response_command.hpp new file mode 100644 index 0000000..002b001 --- /dev/null +++ b/implementation/protocol/include/update_security_policy_response_command.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_HPP_ +#define VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_HPP_ + +#include "security_policy_response_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +class update_security_policy_response_command + : public security_policy_response_command_base { + +public: + update_security_policy_response_command(); +}; + +} // namespace protocol +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_PROTOCOL_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_HPP_ diff --git a/implementation/protocol/src/assign_client_ack_command.cpp b/implementation/protocol/src/assign_client_ack_command.cpp new file mode 100644 index 0000000..b5d19ea --- /dev/null +++ b/implementation/protocol/src/assign_client_ack_command.cpp @@ -0,0 +1,79 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/assign_client_ack_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +assign_client_ack_command::assign_client_ack_command() + : command(id_e::ASSIGN_CLIENT_ACK_ID) { + +} + +void +assign_client_ack_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(assigned_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(sizeof(assigned_)); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + std::memcpy(&_buffer[COMMAND_POSITION_PAYLOAD], &assigned_, + sizeof(assigned_)); +} + +void +assign_client_ack_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(assigned_) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + std::memcpy(&assigned_, &_buffer[COMMAND_POSITION_PAYLOAD], + sizeof(assigned_)); +} + +client_t +assign_client_ack_command::get_assigned() const { + + return (assigned_); +} + +void +assign_client_ack_command::set_assigned(client_t _assigned) { + + assigned_ = _assigned; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/assign_client_command.cpp b/implementation/protocol/src/assign_client_command.cpp new file mode 100644 index 0000000..245ea92 --- /dev/null +++ b/implementation/protocol/src/assign_client_command.cpp @@ -0,0 +1,83 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include +#include "../include/assign_client_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +assign_client_command::assign_client_command() + : command(id_e::ASSIGN_CLIENT_ID) { + +} + +void +assign_client_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + name_.length()); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(name_.length()); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + std::memcpy(&_buffer[COMMAND_POSITION_PAYLOAD], name_.data(), name_.length()); +} + +void +assign_client_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (_buffer.size() < COMMAND_HEADER_SIZE) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // payload? + if (size_ == 0) + return; + + // name + name_.assign(&_buffer[COMMAND_POSITION_PAYLOAD], + &_buffer[_buffer.size()-1]); +} + +std::string +assign_client_command::get_name() const { + + return (name_); +} + +void +assign_client_command::set_name(const std::string &_name) { + + name_ = _name; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/command.cpp b/implementation/protocol/src/command.cpp new file mode 100644 index 0000000..fe338b0 --- /dev/null +++ b/implementation/protocol/src/command.cpp @@ -0,0 +1,66 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +command::command(id_e _id) + : id_(_id), + version_(MAX_SUPPORTED_VERSION), + client_(0), + size_(0) { +} + +void +command::serialize(std::vector &_buffer, + error_e &_error) const { + + // buffer space reservation is done within the code of + // the derived classes that call this method + + _buffer[0] = static_cast(id_); + std::memcpy(&_buffer[COMMAND_POSITION_VERSION], &version_, + sizeof(version_)); + std::memcpy(&_buffer[COMMAND_POSITION_CLIENT], &client_, + sizeof(client_)); + std::memcpy(&_buffer[COMMAND_POSITION_SIZE], &size_, + sizeof(size_)); + + _error = error_e::ERROR_OK; +} + +void +command::deserialize(const std::vector &_buffer, + error_e &_error) { + + // buffer size check (size >= header size) is + // done within the code of the derived classes + // that call this method + + // If the id_ is set to "UNKNOWN", read it. + // Otherwise check it. + if (id_ == id_e::UNKNOWN_ID) { + + id_ = static_cast(_buffer[0]); + } else if (_buffer[0] != static_cast(id_)) { + + _error = error_e::ERROR_MISMATCH; + return; + } + + std::memcpy(&version_, &_buffer[COMMAND_POSITION_VERSION], + sizeof(version_)); + std::memcpy(&client_, &_buffer[COMMAND_POSITION_CLIENT], + sizeof(client_)); + std::memcpy(&size_, &_buffer[COMMAND_POSITION_SIZE], + sizeof(size_)); + + _error = error_e::ERROR_OK; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/deregister_application_command.cpp b/implementation/protocol/src/deregister_application_command.cpp new file mode 100644 index 0000000..5cd6f8d --- /dev/null +++ b/implementation/protocol/src/deregister_application_command.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/deregister_application_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +deregister_application_command::deregister_application_command() + : simple_command(id_e::DEREGISTER_APPLICATION_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/distribute_security_policies_command.cpp b/implementation/protocol/src/distribute_security_policies_command.cpp new file mode 100644 index 0000000..c93b530 --- /dev/null +++ b/implementation/protocol/src/distribute_security_policies_command.cpp @@ -0,0 +1,130 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/distribute_security_policies_command.hpp" +#include "../../security/include/policy.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +distribute_security_policies_command::distribute_security_policies_command() + : command(id_e::DISTRIBUTE_SECURITY_POLICIES_ID) { +} + +void +distribute_security_policies_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + std::min(payload_.size(), size_t(std::numeric_limits::max()))); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize (add) payload + size_t its_offset(COMMAND_HEADER_SIZE); + if (payload_.empty()) { // No policy data (--> set_payloads was not called) + std::memset(&_buffer[its_offset], 0, sizeof(uint32_t)); + } else { + std::memcpy(&_buffer[its_offset], payload_.data(), payload_.size()); + } +} + +void +distribute_security_policies_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(uint32_t) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + uint32_t its_policies_count; + std::memcpy(&its_policies_count, &_buffer[its_offset], + sizeof(its_policies_count)); + its_offset += sizeof(its_policies_count); + + for (uint32_t i = 0; i < its_policies_count; i++) { + + uint32_t its_policy_size; + std::memcpy(&its_policy_size, &_buffer[its_offset], + sizeof(its_policy_size)); + its_offset += sizeof(its_policy_size); + + const byte_t *its_policy_data = &_buffer[its_offset]; + + // set offset to the next policy + its_offset += its_policy_size; + + auto its_policy = std::make_shared(); + if (its_policy_size == 0 + || !its_policy->deserialize(its_policy_data, its_policy_size)) { + + _error = error_e::ERROR_UNKNOWN; + policies_.clear(); + return; + } + + policies_.insert(its_policy); + } +} + +std::set > +distribute_security_policies_command::get_policies() const { + + return (policies_); +} + +void +distribute_security_policies_command::set_payloads( + const std::map > &_payloads) { + + uint32_t its_count(uint32_t(_payloads.size())); + for (uint32_t i = 0; i < sizeof(its_count); ++i) { + payload_.push_back( + reinterpret_cast(&its_count)[i]); + } + + for (const auto &its_uid_gid : _payloads) { + // policy payload length including gid and uid + std::uint32_t its_length(uint32_t(its_uid_gid.second->get_length())); + for (uint32_t i = 0; i < sizeof(its_length); ++i) { + payload_.push_back( + reinterpret_cast(&its_length)[i]); + } + // payload + payload_.insert(payload_.end(), its_uid_gid.second->get_data(), + its_uid_gid.second->get_data() + its_uid_gid.second->get_length()); + } +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/dummy_command.cpp b/implementation/protocol/src/dummy_command.cpp new file mode 100644 index 0000000..0ecc18f --- /dev/null +++ b/implementation/protocol/src/dummy_command.cpp @@ -0,0 +1,40 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/dummy_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +dummy_command::dummy_command() + : command(id_e::UNKNOWN_ID) { + +} + +void +dummy_command::serialize(std::vector &_buffer, + error_e &_error) const { + + (void)_buffer; + _error = error_e::ERROR_NOT_ALLOWED; +} + +void +dummy_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (_buffer.size() < COMMAND_HEADER_SIZE) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + command::deserialize(_buffer, _error); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/expire_command.cpp b/implementation/protocol/src/expire_command.cpp new file mode 100644 index 0000000..0611901 --- /dev/null +++ b/implementation/protocol/src/expire_command.cpp @@ -0,0 +1,64 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/expire_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +expire_command::expire_command() + : subscribe_command_base(id_e::EXPIRE_ID) { +} + +void +expire_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(major_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // payload + subscribe_command_base::serialize(_buffer, _error); +} + +void +expire_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(major_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + subscribe_command_base::deserialize(_buffer, _error); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/multiple_services_command_base.cpp b/implementation/protocol/src/multiple_services_command_base.cpp new file mode 100644 index 0000000..47c8ab2 --- /dev/null +++ b/implementation/protocol/src/multiple_services_command_base.cpp @@ -0,0 +1,119 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/multiple_services_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +multiple_services_command_base::multiple_services_command_base(id_e _id) + : command(_id) { + +} + +void +multiple_services_command_base::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + (services_.size() + * (sizeof(service::service_) + sizeof(service::instance_) + + sizeof(service::major_) + sizeof(service::minor_)))); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + for (const auto &s : services_) { + std::memcpy(&_buffer[its_offset], &s.service_, sizeof(s.service_)); + its_offset += sizeof(s.service_); + std::memcpy(&_buffer[its_offset], &s.instance_, sizeof(s.instance_)); + its_offset += sizeof(s.instance_); + _buffer[its_offset] = s.major_; + its_offset += sizeof(s.major_); + std::memcpy(&_buffer[its_offset], &s.minor_, sizeof(s.minor_)); + its_offset += sizeof(s.minor_); + } +} + +void +multiple_services_command_base::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + size_t its_count = (_buffer.size() - its_offset) / + (sizeof(service::service_) + sizeof(service::instance_) + + sizeof(service::major_) + sizeof(service::minor_)); + + for (size_t i = 0; i < its_count; i++) { + service its_service; + + std::memcpy(&its_service.service_, &_buffer[its_offset], + sizeof(its_service.service_)); + its_offset += sizeof(its_service.service_); + std::memcpy(&its_service.instance_, &_buffer[its_offset], + sizeof(its_service.instance_)); + its_offset += sizeof(its_service.instance_); + std::memcpy(&its_service.major_, &_buffer[its_offset], + sizeof(its_service.major_)); + its_offset += sizeof(its_service.major_); + std::memcpy(&its_service.minor_, &_buffer[its_offset], + sizeof(its_service.minor_)); + its_offset += sizeof(its_service.minor_); + + services_.insert(its_service); + } +} + +std::set +multiple_services_command_base::get_services() const { + + return (services_); +} + +void +multiple_services_command_base::set_services(const std::set &_services) { + + services_ = _services; +} + +void +multiple_services_command_base::add_service(const service &_service) { + + services_.insert(_service); +} + + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/offer_service_command.cpp b/implementation/protocol/src/offer_service_command.cpp new file mode 100644 index 0000000..286a6f7 --- /dev/null +++ b/implementation/protocol/src/offer_service_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/offer_service_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +offer_service_command::offer_service_command() + : service_command_base(id_e::OFFER_SERVICE_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/offered_services_request_command.cpp b/implementation/protocol/src/offered_services_request_command.cpp new file mode 100644 index 0000000..3a0aa95 --- /dev/null +++ b/implementation/protocol/src/offered_services_request_command.cpp @@ -0,0 +1,78 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/offered_services_request_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +offered_services_request_command::offered_services_request_command() + : command(id_e::OFFERED_SERVICES_REQUEST_ID) { +} + +void +offered_services_request_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(offer_type_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(sizeof(offer_type_)); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + std::memcpy(&_buffer[COMMAND_POSITION_PAYLOAD], &offer_type_, + sizeof(offer_type_)); +} + +void +offered_services_request_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(offer_type_) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + std::memcpy(&offer_type_, &_buffer[COMMAND_POSITION_PAYLOAD], + sizeof(offer_type_)); +} + +offer_type_e +offered_services_request_command::get_offer_type() const { + + return (offer_type_); +} + +void +offered_services_request_command::set_offer_type(offer_type_e _offer_type) { + + offer_type_ = _offer_type; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/offered_services_response_command.cpp b/implementation/protocol/src/offered_services_response_command.cpp new file mode 100644 index 0000000..bc8df95 --- /dev/null +++ b/implementation/protocol/src/offered_services_response_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/offered_services_response_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +offered_services_response_command::offered_services_response_command() + : multiple_services_command_base(id_e::OFFERED_SERVICES_RESPONSE_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/ping_command.cpp b/implementation/protocol/src/ping_command.cpp new file mode 100644 index 0000000..fab227b --- /dev/null +++ b/implementation/protocol/src/ping_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/ping_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +ping_command::ping_command() + : simple_command(id_e::PING_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/pong_command.cpp b/implementation/protocol/src/pong_command.cpp new file mode 100644 index 0000000..8be1e90 --- /dev/null +++ b/implementation/protocol/src/pong_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/pong_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +pong_command::pong_command() + : simple_command(id_e::PONG_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/register_application_command.cpp b/implementation/protocol/src/register_application_command.cpp new file mode 100644 index 0000000..d8babc7 --- /dev/null +++ b/implementation/protocol/src/register_application_command.cpp @@ -0,0 +1,81 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/register_application_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +register_application_command::register_application_command() + : command(id_e::REGISTER_APPLICATION_ID), + port_(ILLEGAL_PORT) { + +} + +void +register_application_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(port_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(sizeof(port_)); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + std::memcpy(&_buffer[COMMAND_POSITION_PAYLOAD], &port_, + sizeof(port_)); + +} + +void +register_application_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(port_) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + std::memcpy(&port_, &_buffer[COMMAND_POSITION_PAYLOAD], + sizeof(port_)); +} + +port_t +register_application_command::get_port() const { + + return (port_); +} + +void +register_application_command::set_port(port_t _port) { + + port_ = _port; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/register_event.cpp b/implementation/protocol/src/register_event.cpp new file mode 100644 index 0000000..5be91b6 --- /dev/null +++ b/implementation/protocol/src/register_event.cpp @@ -0,0 +1,82 @@ +#include "../include/register_event.hpp" +#include + +namespace vsomeip_v3 { +namespace protocol { + +register_event::register_event(service_t service, instance_t instance, + event_t event, event_type_e event_type, + bool is_provided, reliability_type_e reliability, + bool is_cyclic, uint16_t num_eventg, + const std::set &eventgroups): + service_(service), instance_(instance), event_(event), + event_type_(event_type), is_provided_(is_provided), + reliability_(reliability), is_cyclic_(is_cyclic), + num_eventg_(num_eventg), eventgroups_(eventgroups) { +} + +void +register_event::serialize(std::vector &_buffer, size_t &_offset) const { + + std::memcpy(&_buffer[_offset], &service_, sizeof(service_)); + _offset += sizeof(service_); + std::memcpy(&_buffer[_offset], &instance_, sizeof(instance_)); + _offset += sizeof(instance_); + std::memcpy(&_buffer[_offset], &event_, sizeof(event_)); + _offset += sizeof(event_); + _buffer[_offset] = static_cast(event_type_); + _offset += sizeof(event_type_); + _buffer[_offset] = static_cast(is_provided_); + _offset += sizeof(is_provided_); + _buffer[_offset] = static_cast(reliability_); + _offset += sizeof(reliability_); + _buffer[_offset] = static_cast(is_cyclic_); + _offset += sizeof(is_cyclic_); + std::memcpy(&_buffer[_offset], &num_eventg_, sizeof(num_eventg_)); + _offset += sizeof(num_eventg_); + + for (const auto g : eventgroups_) { + std::memcpy(&_buffer[_offset], &g, sizeof(g)); + _offset += sizeof(g); + } +} + +void +register_event::deserialize(const std::vector &_buffer, size_t &_offset) { + + std::memcpy(&service_, &_buffer[_offset], sizeof(service_)); + _offset += sizeof(service_); + std::memcpy(&instance_, &_buffer[_offset], sizeof(instance_)); + _offset += sizeof(instance_); + std::memcpy(&event_, &_buffer[_offset], sizeof(event_)); + _offset += sizeof(event_); + event_type_ = static_cast(_buffer[_offset]); + _offset += sizeof(event_type_); + is_provided_ = static_cast(_buffer[_offset]); + _offset += sizeof(is_provided_); + reliability_ = static_cast(_buffer[_offset]); + _offset += sizeof(reliability_); + is_cyclic_ = static_cast(_buffer[_offset]); + _offset += sizeof(is_cyclic_); + std::memcpy(&num_eventg_, &_buffer[_offset], sizeof(num_eventg_)); + _offset += sizeof(num_eventg_); + + eventgroups_.clear(); + for (size_t i = 0; i < num_eventg_; i++) { + eventgroup_t its_g; + std::memcpy(&its_g, &_buffer[_offset], sizeof(its_g)); + _offset += sizeof(its_g); + + eventgroups_.insert(its_g); + } +} + +void +register_event::set_eventgroups(const std::set &_eventgroups) { + + eventgroups_ = _eventgroups; + num_eventg_ = (uint16_t)eventgroups_.size(); +} + +} // namespace protocol +} // namespace vsomeip_v3 diff --git a/implementation/protocol/src/register_events_command.cpp b/implementation/protocol/src/register_events_command.cpp new file mode 100644 index 0000000..830e223 --- /dev/null +++ b/implementation/protocol/src/register_events_command.cpp @@ -0,0 +1,110 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/register_events_command.hpp" +#include + +namespace vsomeip_v3 { +namespace protocol { + +register_events_command::register_events_command() + : command(id_e::REGISTER_EVENT_ID) { +} + +bool +register_events_command::add_registration(const register_event &_register_event) { + + size_t its_size(size_ + COMMAND_HEADER_SIZE + + sizeof(_register_event.get_service()) + sizeof(_register_event.get_instance()) + + sizeof(_register_event.get_event()) + sizeof(_register_event.get_event_type()) + + sizeof(_register_event.is_provided()) + sizeof(_register_event.get_reliability()) + + sizeof(_register_event.is_cyclic()) + sizeof(_register_event.get_num_eventgroups()) + + (_register_event.get_num_eventgroups() * sizeof(eventgroup_t) )); + if (its_size > std::numeric_limits::max()) { + return false; + } else { + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + registrations_.push_back(_register_event); + } + return true; +} + +void +register_events_command::serialize(std::vector &_buffer, error_e &_error) const { + + if (size_ + COMMAND_HEADER_SIZE> std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(size_+COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + for(auto ® : registrations_) { + reg.serialize(_buffer, its_offset); + } +} + +void +register_events_command::deserialize(const std::vector &_buffer, error_e &_error) { + registrations_.clear(); + + if(_buffer.size() < COMMAND_HEADER_SIZE) { + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + size_t its_offset(COMMAND_HEADER_SIZE); + + while(its_offset < _buffer.size()) { + size_t its_size(its_offset+ sizeof(service_t) + sizeof(instance_t) + + sizeof(event_t) + sizeof(event_type_e) + + sizeof(bool) + sizeof(bool) + sizeof(bool) + sizeof(uint16_t) + + sizeof(eventgroup_t)); // at least one is needed + if (its_size > _buffer.size()) { + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + register_event event_command; + event_command.deserialize(_buffer, its_offset); + registrations_.push_back(event_command); + } +} + +std::size_t +register_events_command::get_num_registrations() const { + + return registrations_.size(); +} + +bool +register_events_command::get_registration_at(std::size_t _position, register_event & _reg) const { + + if(_position < registrations_.size()) { + _reg = registrations_[_position]; + return true; + } + return false; +} + +} // namespace protocol +} // namespace vsomeip_v3 diff --git a/implementation/protocol/src/registered_ack_command.cpp b/implementation/protocol/src/registered_ack_command.cpp new file mode 100644 index 0000000..a9df5d3 --- /dev/null +++ b/implementation/protocol/src/registered_ack_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/registered_ack_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +registered_ack_command::registered_ack_command() + : simple_command(id_e::REGISTERED_ACK_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/release_service_command.cpp b/implementation/protocol/src/release_service_command.cpp new file mode 100644 index 0000000..41475ec --- /dev/null +++ b/implementation/protocol/src/release_service_command.cpp @@ -0,0 +1,101 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/release_service_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +release_service_command::release_service_command() + : command(id_e::RELEASE_SERVICE_ID) { + +} + +void +release_service_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service::service_) + sizeof(service::instance_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&_buffer[its_offset], &service_.service_, sizeof(service_.service_)); + its_offset += sizeof(service_.service_); + std::memcpy(&_buffer[its_offset], &service_.instance_, sizeof(service_.instance_)); +} + +void +release_service_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service::service_) + sizeof(service::instance_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&service_.service_, &_buffer[its_offset], + sizeof(service_.service_)); + its_offset += sizeof(service_.service_); + std::memcpy(&service_.instance_, &_buffer[its_offset], + sizeof(service_.instance_)); +} + +service_t +release_service_command::get_service() const { + + return (service_.service_); +} + +void +release_service_command::set_service(service_t _service) { + + service_.service_ = _service; +} + +instance_t +release_service_command::get_instance() const { + + return (service_.instance_); +} + +void +release_service_command::set_instance(instance_t _instance) { + + service_.instance_ = _instance; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/remove_security_policy_command.cpp b/implementation/protocol/src/remove_security_policy_command.cpp new file mode 100644 index 0000000..acf8aed --- /dev/null +++ b/implementation/protocol/src/remove_security_policy_command.cpp @@ -0,0 +1,114 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/remove_security_policy_command.hpp" +#include "../../security/include/policy.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +remove_security_policy_command::remove_security_policy_command() + : command(id_e::REMOVE_SECURITY_POLICY_ID) { +} + +void +remove_security_policy_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(update_id_) + + sizeof(uid_) + sizeof(gid_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&_buffer[its_offset], &update_id_, sizeof(update_id_)); + its_offset += sizeof(update_id_); + std::memcpy(&_buffer[its_offset], &uid_, sizeof(uid_)); + its_offset += sizeof(uid_); + std::memcpy(&_buffer[its_offset], &gid_, sizeof(gid_)); +} + +void +remove_security_policy_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(update_id_) + + sizeof(uid_) + sizeof(gid_t) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&update_id_, &_buffer[its_offset], sizeof(update_id_)); + its_offset += sizeof(update_id_); + std::memcpy(&uid_, &_buffer[its_offset], sizeof(uid_)); + its_offset += sizeof(uid_); + std::memcpy(&gid_, &_buffer[its_offset], sizeof(gid_)); +} + +uint32_t +remove_security_policy_command::get_update_id() const { + + return (update_id_); +} + +void +remove_security_policy_command::set_update_id(uint32_t _update_id) { + + update_id_ = _update_id; +} + + +uid_t +remove_security_policy_command::get_uid() const { + + return (uid_); +} + +void +remove_security_policy_command::set_uid(uid_t _uid) { + + uid_ = _uid; +} + +gid_t +remove_security_policy_command::get_gid() const { + + return (gid_); +} + +void +remove_security_policy_command::set_gid(gid_t _gid) { + + gid_ = _gid; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/remove_security_policy_response_command.cpp b/implementation/protocol/src/remove_security_policy_response_command.cpp new file mode 100644 index 0000000..ce8ab0b --- /dev/null +++ b/implementation/protocol/src/remove_security_policy_response_command.cpp @@ -0,0 +1,18 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/remove_security_policy_response_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +remove_security_policy_response_command::remove_security_policy_response_command() + : security_policy_response_command_base( + id_e::REMOVE_SECURITY_POLICY_RESPONSE_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/request_service_command.cpp b/implementation/protocol/src/request_service_command.cpp new file mode 100644 index 0000000..c98f8eb --- /dev/null +++ b/implementation/protocol/src/request_service_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/request_service_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +request_service_command::request_service_command() + : multiple_services_command_base(id_e::REQUEST_SERVICE_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/resend_provided_events_command.cpp b/implementation/protocol/src/resend_provided_events_command.cpp new file mode 100644 index 0000000..929a434 --- /dev/null +++ b/implementation/protocol/src/resend_provided_events_command.cpp @@ -0,0 +1,80 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/resend_provided_events_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +resend_provided_events_command::resend_provided_events_command() + : command(id_e::RESEND_PROVIDED_EVENTS_ID) { + +} + +void +resend_provided_events_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(remote_offer_id_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(sizeof(remote_offer_id_)); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + std::memcpy(&_buffer[COMMAND_POSITION_PAYLOAD], &remote_offer_id_, + sizeof(remote_offer_id_)); +} + +void +resend_provided_events_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(remote_offer_id_) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + std::memcpy(&remote_offer_id_, &_buffer[COMMAND_POSITION_PAYLOAD], + sizeof(remote_offer_id_)); +} + +pending_remote_offer_id_t +resend_provided_events_command::get_remote_offer_id() const { + + return (remote_offer_id_); +} + +void +resend_provided_events_command::set_remote_offer_id( + pending_remote_offer_id_t _remote_offer_id) { + + remote_offer_id_ = _remote_offer_id; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/routing_info_command.cpp b/implementation/protocol/src/routing_info_command.cpp new file mode 100644 index 0000000..ae2747f --- /dev/null +++ b/implementation/protocol/src/routing_info_command.cpp @@ -0,0 +1,98 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/routing_info_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +routing_info_command::routing_info_command() + : command(id_e::ROUTING_INFO_ID) { + +} + +void +routing_info_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE); + for (const auto &e : entries_) + its_size += e.get_size(); + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t _index(COMMAND_HEADER_SIZE); + for (const auto &e : entries_) { + e.serialize(_buffer, _index, _error); + if (_error != error_e::ERROR_OK) { + _buffer.clear(); + return; + } + } +} + +void +routing_info_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + + // deserialize payload + size_t its_index(COMMAND_HEADER_SIZE); + while (its_index < _buffer.size()) { + + routing_info_entry its_entry; + its_entry.deserialize(_buffer, its_index, _error); + + if (_error == error_e::ERROR_OK) + entries_.emplace_back(its_entry); + else + break; + } +} + +// specific +const std::vector & +routing_info_command::get_entries() const { + + return (entries_); +} + +void +routing_info_command::set_entries(std::vector &&_entries) { + + entries_ = std::move(_entries); +} + +void +routing_info_command::add_entry(const routing_info_entry &_entry) { + + entries_.push_back(_entry); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/routing_info_entry.cpp b/implementation/protocol/src/routing_info_entry.cpp new file mode 100644 index 0000000..1edb23b --- /dev/null +++ b/implementation/protocol/src/routing_info_entry.cpp @@ -0,0 +1,304 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include + +#include +#include + +#include "../include/routing_info_entry.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +routing_info_entry::routing_info_entry() + : type_(routing_info_entry_type_e::RIE_UNKNOWN), + port_(0) { + +} + +routing_info_entry::routing_info_entry(const routing_info_entry &_source) + : type_(_source.type_), + client_(_source.client_), + address_(_source.address_), + port_(_source.port_), + services_(_source.services_) { + +} + +void +routing_info_entry::serialize(std::vector &_buffer, + size_t &_index, error_e &_error) const { + + _buffer[_index] = static_cast(type_); + _index += sizeof(type_); + + // Size is overall size - size field - command type + size_t its_size = get_size() - sizeof(uint32_t) - 1; + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MALFORMED; + return; + } + + uint32_t its_size32(static_cast(its_size)); + std::memcpy(&_buffer[_index], &its_size32, sizeof(its_size32)); + _index += sizeof(its_size32); + + uint32_t its_client_size(sizeof(client_)); + if (!address_.is_unspecified()) { + if (address_.is_v4()) { + its_client_size += uint32_t(sizeof(boost::asio::ip::address_v4::bytes_type) + + sizeof(port_)); + } else { + its_client_size += uint32_t(sizeof(boost::asio::ip::address_v6::bytes_type) + + sizeof(port_)); + } + } + + if (type_ > routing_info_entry_type_e::RIE_DELETE_CLIENT) { + + std::memcpy(&_buffer[_index], &its_client_size, sizeof(its_client_size)); + _index += sizeof(its_client_size); + } + + std::memcpy(&_buffer[_index], &client_, sizeof(client_)); + _index += sizeof(client_); + + if (!address_.is_unspecified()) { + + if (address_.is_v4()) { + std::memcpy(&_buffer[_index], address_.to_v4().to_bytes().data(), + sizeof(boost::asio::ip::address_v4::bytes_type)); + _index += sizeof(boost::asio::ip::address_v4::bytes_type); + } else { + std::memcpy(&_buffer[_index], address_.to_v6().to_bytes().data(), + sizeof(boost::asio::ip::address_v6::bytes_type)); + _index += sizeof(boost::asio::ip::address_v6::bytes_type); + } + std::memcpy(&_buffer[_index], &port_, sizeof(port_)); + _index += sizeof(port_); + } + + if (type_ > routing_info_entry_type_e::RIE_DELETE_CLIENT) { + + its_size = (services_.size() * + (sizeof(service_t) + sizeof(instance_t) + + sizeof(major_version_t) + sizeof(minor_version_t))); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MALFORMED; + return; + } + + its_size32 = static_cast(its_size); + std::memcpy(&_buffer[_index], &its_size32, sizeof(its_size32)); + _index += sizeof(its_size32); + + for (const auto &s : services_) { + + std::memcpy(&_buffer[_index], &s.service_, sizeof(s.service_)); + _index += sizeof(s.service_); + std::memcpy(&_buffer[_index], &s.instance_, sizeof(s.instance_)); + _index += sizeof(s.instance_); + std::memcpy(&_buffer[_index], &s.major_, sizeof(s.major_)); + _index += sizeof(s.major_); + std::memcpy(&_buffer[_index], &s.minor_, sizeof(s.minor_)); + _index += sizeof(s.minor_); + } + } +} + +void +routing_info_entry::deserialize(const std::vector &_buffer, + size_t &_index, error_e &_error) { + + uint32_t its_size; + uint32_t its_client_size; + + if (_buffer.size() < _index + sizeof(type_) + sizeof(its_size) + + sizeof(client_)) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + type_ = static_cast(_buffer[_index++]); + if (type_ == routing_info_entry_type_e::RIE_UNKNOWN) { + + _error = error_e::ERROR_MALFORMED; + return; + } + + std::memcpy(&its_size, &_buffer[_index], sizeof(its_size)); + _index += sizeof(its_size); + + if (type_ > routing_info_entry_type_e::RIE_DELETE_CLIENT) { + std::memcpy(&its_client_size, &_buffer[_index], sizeof(its_client_size)); + _index += sizeof(its_client_size); + } else { + its_client_size = its_size; + } + + std::memcpy(&client_, &_buffer[_index], sizeof(client_)); + _index += sizeof(client_); + + if (its_client_size > sizeof(client_)) { + + uint32_t its_address_size = its_client_size + - uint32_t(sizeof(client_t) + sizeof(port_)); + + if (its_address_size == sizeof(boost::asio::ip::address_v4::bytes_type)) { + + boost::asio::ip::address_v4::bytes_type its_array; + std::memcpy(&its_array, &_buffer[_index], its_array.size()); + address_ = boost::asio::ip::address_v4(its_array); + _index += its_array.size(); + + } else if (its_address_size == sizeof(boost::asio::ip::address_v6::bytes_type)) { + + boost::asio::ip::address_v6::bytes_type its_array; + std::memcpy(&its_array, &_buffer[_index], its_array.size()); + address_ = boost::asio::ip::address_v6(its_array); + _index += its_array.size(); + + } else { + + _error = error_e::ERROR_MALFORMED; + return; + } + + std::memcpy(&port_, &_buffer[_index], sizeof(port_)); + _index += sizeof(port_); + } + + if (type_ > routing_info_entry_type_e::RIE_DELETE_CLIENT) { + + if (_buffer.size() < _index + sizeof(its_size)) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + std::memcpy(&its_size, &_buffer[_index], sizeof(its_size)); + _index += sizeof(its_size); + + if (_buffer.size() < _index + its_size) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + size_t its_n = (its_size / + (sizeof(service_t) + sizeof(instance_t) + + sizeof(major_version_t) + sizeof(minor_version_t))); + + for (size_t i = 0; i < its_n; i++) { + + service its_service; + std::memcpy(&its_service.service_, &_buffer[_index], sizeof(its_service.service_)); + _index += sizeof(its_service.service_); + std::memcpy(&its_service.instance_, &_buffer[_index], sizeof(its_service.instance_)); + _index += sizeof(its_service.instance_); + its_service.major_ = static_cast(_buffer[_index]); + _index += sizeof(its_service.major_); + std::memcpy(&its_service.minor_, &_buffer[_index], sizeof(its_service.minor_)); + _index += sizeof(its_service.minor_); + + services_.emplace_back(its_service); + } + } +} + +routing_info_entry_type_e +routing_info_entry::get_type() const { + + return (type_); +} + +void +routing_info_entry::set_type(routing_info_entry_type_e _type) { + + type_ = _type; +} + +size_t +routing_info_entry::get_size() const { + + size_t its_size(ROUTING_INFO_ENTRY_HEADER_SIZE); + + if (!address_.is_unspecified()) { + if (address_.is_v4()) { + its_size += (sizeof(boost::asio::ip::address_v4::bytes_type) + + sizeof(port_)); + } else { + its_size += (sizeof(boost::asio::ip::address_v6::bytes_type) + + sizeof(port_)); + } + } + + if (type_ > routing_info_entry_type_e::RIE_DELETE_CLIENT) { + its_size += sizeof(uint32_t); // size of the client info + its_size += sizeof(uint32_t); // size of the services array + its_size += (services_.size() * + (sizeof(service_t) + sizeof(instance_t) + + sizeof(major_version_t) + sizeof(minor_version_t))); + } + + return (its_size); +} + +client_t +routing_info_entry::get_client() const { + + return (client_); +} + +void +routing_info_entry::set_client(client_t _client) { + + client_ = _client; +} + +boost::asio::ip::address +routing_info_entry::get_address() const { + + return (address_); +} + +void +routing_info_entry::set_address(const boost::asio::ip::address &_address) { + + address_ = _address; +} + +port_t +routing_info_entry::get_port() const { + + return (port_); +} + +void +routing_info_entry::set_port(port_t _port) { + + port_ = _port; +} + +const std::vector & +routing_info_entry::get_services() const { + + return (services_); +} + +void +routing_info_entry::add_service(const service &_service) { + + services_.push_back(_service); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/security_policy_response_command_base.cpp b/implementation/protocol/src/security_policy_response_command_base.cpp new file mode 100644 index 0000000..2a4837a --- /dev/null +++ b/implementation/protocol/src/security_policy_response_command_base.cpp @@ -0,0 +1,80 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/security_policy_response_command_base.hpp" +#include "../../security/include/policy.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +security_policy_response_command_base::security_policy_response_command_base( + id_e _id) + : command(_id) { +} + +void +security_policy_response_command_base::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(update_id_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&_buffer[its_offset], &update_id_, sizeof(update_id_)); +} + +void +security_policy_response_command_base::deserialize( + const std::vector &_buffer, error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(update_id_) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + std::memcpy(&update_id_, &_buffer[COMMAND_POSITION_PAYLOAD], + sizeof(update_id_)); +} + +uint32_t +security_policy_response_command_base::get_update_id() const { + + return (update_id_); +} + +void +security_policy_response_command_base::set_update_id(uint32_t _update_id) { + + update_id_ = _update_id; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/send_command.cpp b/implementation/protocol/src/send_command.cpp new file mode 100644 index 0000000..7959744 --- /dev/null +++ b/implementation/protocol/src/send_command.cpp @@ -0,0 +1,149 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/send_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +send_command::send_command(id_e _id) + : command(_id) { +} + +instance_t +send_command::get_instance() const { + + return instance_; +} + +void +send_command::set_instance(instance_t _instance) { + + instance_ = _instance; +} + +bool +send_command::is_reliable() const { + + return is_reliable_; +} + +void +send_command::set_reliable(bool _is_reliable) { + + is_reliable_ = _is_reliable; +} + +uint8_t +send_command::get_status() const { + + return status_; +} + +void +send_command::set_status(uint8_t _status) { + + status_ = _status; +} + +client_t +send_command::get_target() const { + + return target_; +} + +void +send_command::set_target(client_t _target) { + + target_ = _target; +} + +std::vector +send_command::get_message() const { + + return message_; +} + +void +send_command::set_message(const std::vector &_message) { + + message_ = std::move(_message); +} + +void +send_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(instance_) + + sizeof(is_reliable_) + sizeof(status_) + + sizeof(target_) + message_.size()); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&_buffer[its_offset], &instance_, sizeof(instance_)); + its_offset += sizeof(instance_); + _buffer[its_offset] = static_cast(is_reliable_); + its_offset += sizeof(is_reliable_); + _buffer[its_offset] = static_cast(status_); + its_offset += sizeof(status_); + std::memcpy(&_buffer[its_offset], &target_, sizeof(target_)); + its_offset += sizeof(target_); + std::memcpy(&_buffer[its_offset], &message_[0], message_.size()); +} + +void +send_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(instance_) + + sizeof(is_reliable_) + sizeof(status_) + + sizeof(target_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&instance_, &_buffer[its_offset], sizeof(instance_)); + its_offset += sizeof(instance_); + is_reliable_ = static_cast(_buffer[its_offset]); + its_offset += sizeof(is_reliable_); + status_ = static_cast(_buffer[its_offset]); + its_offset += sizeof(status_); + std::memcpy(&target_, &_buffer[its_offset], sizeof(target_)); + its_offset += sizeof(target_); + message_.resize(_buffer.size() - its_offset); + std::memcpy(&message_[0], &_buffer[its_offset], message_.size()); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/service_command_base.cpp b/implementation/protocol/src/service_command_base.cpp new file mode 100644 index 0000000..ae270f2 --- /dev/null +++ b/implementation/protocol/src/service_command_base.cpp @@ -0,0 +1,130 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/service_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +service_command_base::service_command_base(id_e _id) + : command(_id) { +} + +service_t +service_command_base::get_service() const { + + return service_.service_; +} + +void +service_command_base::set_service(service_t _service) { + + service_.service_ = _service; +} + +instance_t +service_command_base::get_instance() const { + + return service_.instance_; +} + +void +service_command_base::set_instance(instance_t _instance) { + + service_.instance_ = _instance; +} + +major_version_t +service_command_base::get_major() const { + + return service_.major_; +} + +void +service_command_base::set_major(major_version_t _major) { + + service_.major_ = _major; +} + +minor_version_t +service_command_base::get_minor() const { + + return service_.minor_; +} + +void +service_command_base::set_minor(minor_version_t _minor) { + + service_.minor_ = _minor; +} + +void +service_command_base::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_.service_) + sizeof(service_.instance_) + + sizeof(service_.major_) + sizeof(service_.minor_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&_buffer[its_offset], &service_.service_, sizeof(service_.service_)); + its_offset += sizeof(service_.service_); + std::memcpy(&_buffer[its_offset], &service_.instance_, sizeof(service_.instance_)); + its_offset += sizeof(service_.instance_); + _buffer[its_offset] = service_.major_; + its_offset += sizeof(service_.major_); + std::memcpy(&_buffer[its_offset], &service_.minor_, sizeof(service_.minor_)); +} + +void +service_command_base::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_.service_) + sizeof(service_.instance_) + + sizeof(service_.major_) + sizeof(service_.minor_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + + // deserialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&service_.service_, &_buffer[its_offset], sizeof(service_.service_)); + its_offset += sizeof(service_.service_); + std::memcpy(&service_.instance_, &_buffer[its_offset], sizeof(service_.instance_)); + its_offset += sizeof(service_.instance_); + service_.major_ = _buffer[its_offset]; + its_offset += sizeof(service_.major_); + std::memcpy(&service_.minor_, &_buffer[its_offset], sizeof(service_.minor_)); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/simple_command.cpp b/implementation/protocol/src/simple_command.cpp new file mode 100644 index 0000000..9076012 --- /dev/null +++ b/implementation/protocol/src/simple_command.cpp @@ -0,0 +1,48 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/simple_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +simple_command::simple_command(id_e _id) + : command(_id) { + +} + +void +simple_command::serialize(std::vector &_buffer, + error_e &_error) const { + + // no size check as we know this is small enough + + // resize buffer + _buffer.resize(COMMAND_HEADER_SIZE); + + // set size + size_ = 0; + + // serialize header + command::serialize(_buffer, _error); +} + +void +simple_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (_buffer.size() < COMMAND_HEADER_SIZE) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + command::deserialize(_buffer, _error); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/stop_offer_service_command.cpp b/implementation/protocol/src/stop_offer_service_command.cpp new file mode 100644 index 0000000..c12a20d --- /dev/null +++ b/implementation/protocol/src/stop_offer_service_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/stop_offer_service_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +stop_offer_service_command::stop_offer_service_command() + : service_command_base(id_e::STOP_OFFER_SERVICE_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/subscribe_ack_command.cpp b/implementation/protocol/src/subscribe_ack_command.cpp new file mode 100644 index 0000000..12fe1cd --- /dev/null +++ b/implementation/protocol/src/subscribe_ack_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/subscribe_ack_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +subscribe_ack_command::subscribe_ack_command() + : subscribe_ack_command_base(id_e::SUBSCRIBE_ACK_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/subscribe_ack_command_base.cpp b/implementation/protocol/src/subscribe_ack_command_base.cpp new file mode 100644 index 0000000..2a88972 --- /dev/null +++ b/implementation/protocol/src/subscribe_ack_command_base.cpp @@ -0,0 +1,174 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/subscribe_ack_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +subscribe_ack_command_base::subscribe_ack_command_base(id_e _id) + : command(_id), + service_(ANY_SERVICE), + instance_(ANY_INSTANCE), + eventgroup_(0), + subscriber_(0), + event_(ANY_EVENT), + pending_id_(0) { +} + +service_t +subscribe_ack_command_base::get_service() const { + + return service_; +} + +void +subscribe_ack_command_base::set_service(service_t _service) { + + service_ = _service; +} + +instance_t +subscribe_ack_command_base::get_instance() const { + + return instance_; +} + +void +subscribe_ack_command_base::set_instance(instance_t _instance) { + + instance_ = _instance; +} + +eventgroup_t +subscribe_ack_command_base::get_eventgroup() const { + + return eventgroup_; +} + +void +subscribe_ack_command_base::set_eventgroup(eventgroup_t _eventgroup) { + + eventgroup_ = _eventgroup; +} + +client_t +subscribe_ack_command_base::get_subscriber() const { + + return subscriber_; +} + +void +subscribe_ack_command_base::set_subscriber(client_t _subscriber) { + + subscriber_ = _subscriber; +} + +event_t +subscribe_ack_command_base::get_event() const { + + return event_; +} + +void +subscribe_ack_command_base::set_event(event_t _event) { + + event_ = _event; +} + +pending_id_t +subscribe_ack_command_base::get_pending_id() const { + + return pending_id_; +} + +void +subscribe_ack_command_base::set_pending_id(pending_id_t _pending_id) { + + pending_id_ = _pending_id; +} + +void +subscribe_ack_command_base::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(subscriber_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&_buffer[its_offset], &service_, sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&_buffer[its_offset], &instance_, sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&_buffer[its_offset], &eventgroup_, sizeof(eventgroup_)); + its_offset += sizeof(instance_); + std::memcpy(&_buffer[its_offset], &subscriber_, sizeof(subscriber_)); + its_offset += sizeof(subscriber_); + std::memcpy(&_buffer[its_offset], &event_, sizeof(event_)); + its_offset += sizeof(event_); + std::memcpy(&_buffer[its_offset], &pending_id_, sizeof(pending_id_)); +} + +void +subscribe_ack_command_base::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(subscriber_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&service_, &_buffer[its_offset], sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&instance_, &_buffer[its_offset], sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&eventgroup_, &_buffer[its_offset], sizeof(eventgroup_)); + its_offset += sizeof(eventgroup_); + std::memcpy(&subscriber_, &_buffer[its_offset], sizeof(subscriber_)); + its_offset += sizeof(subscriber_); + std::memcpy(&event_, &_buffer[its_offset], sizeof(event_)); + its_offset += sizeof(event_); + std::memcpy(&pending_id_, &_buffer[its_offset], sizeof(pending_id_)); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/subscribe_command.cpp b/implementation/protocol/src/subscribe_command.cpp new file mode 100644 index 0000000..89f19af --- /dev/null +++ b/implementation/protocol/src/subscribe_command.cpp @@ -0,0 +1,144 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/subscribe_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +subscribe_command::subscribe_command() + : subscribe_command_base(id_e::SUBSCRIBE_ID) { +} + +std::shared_ptr +subscribe_command::get_filter() const { + + return filter_; +} + +void +subscribe_command::set_filter( + const std::shared_ptr &_filter) { + + filter_ = _filter; +} + +void +subscribe_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(major_) + + sizeof(event_) + sizeof(pending_id_)); + size_t its_offset(its_size); + + if (filter_) { + its_size += sizeof(filter_->on_change_) + + sizeof(filter_->on_change_resets_interval_) + + sizeof(filter_->interval_) + + (filter_->ignore_.size() * (sizeof(size_t) + sizeof(byte_t))); + } + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + subscribe_command_base::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + if (filter_) { + + _buffer[its_offset] = static_cast(filter_->on_change_); + its_offset += sizeof(filter_->on_change_); + _buffer[its_offset] = static_cast(filter_->on_change_resets_interval_); + its_offset += sizeof(filter_->on_change_resets_interval_); + std::memcpy(&_buffer[its_offset], &filter_->interval_, sizeof(filter_->interval_)); + its_offset += sizeof(filter_->interval_); + for (const auto &its_ignore : filter_->ignore_) { + std::memcpy(&_buffer[its_offset], &its_ignore.first, sizeof(size_t)); + its_offset += sizeof(size_t); + _buffer[its_offset] = its_ignore.second; + its_offset += sizeof(byte_t); + } + } +} + +void +subscribe_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(major_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize subscription + subscribe_command_base::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize filter + size_t its_offset(its_size); + if (_buffer.size() - its_offset + >= sizeof(bool) + sizeof(bool) + sizeof(int64_t)) { + + filter_ = std::make_shared(); + std::memcpy(&filter_->on_change_, &_buffer[its_offset], sizeof(filter_->on_change_)); + its_offset += sizeof(filter_->on_change_); + std::memcpy(&filter_->on_change_resets_interval_, &_buffer[its_offset], sizeof(filter_->on_change_resets_interval_)); + its_offset += sizeof(filter_->on_change_resets_interval_); + std::memcpy(&filter_->interval_, &_buffer[its_offset], sizeof(filter_->interval_)); + its_offset += sizeof(filter_->interval_); + + while (_buffer.size() - its_offset + >= sizeof(size_t) + sizeof(byte_t)) { + + size_t its_key; + byte_t its_value; + + std::memcpy(&its_key, &_buffer[its_offset], sizeof(its_key)); + if (filter_->ignore_.find(its_key) != filter_->ignore_.end()) { + + _error = error_e::ERROR_MALFORMED; + return; + } + + its_offset += sizeof(its_key); + its_value = _buffer[its_offset]; + its_offset += sizeof(its_value); + + filter_->ignore_.emplace(std::make_pair(its_key, its_value)); + } + } +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/subscribe_command_base.cpp b/implementation/protocol/src/subscribe_command_base.cpp new file mode 100644 index 0000000..cd5644a --- /dev/null +++ b/implementation/protocol/src/subscribe_command_base.cpp @@ -0,0 +1,146 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/subscribe_command_base.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +subscribe_command_base::subscribe_command_base(id_e _id) + : command(_id), + service_(ANY_SERVICE), + instance_(ANY_INSTANCE), + eventgroup_(0), + major_(ANY_MAJOR), + event_(ANY_EVENT), + pending_id_(0) { +} + +service_t +subscribe_command_base::get_service() const { + + return service_; +} + +void +subscribe_command_base::set_service(service_t _service) { + + service_ = _service; +} + +instance_t +subscribe_command_base::get_instance() const { + + return instance_; +} + +void +subscribe_command_base::set_instance(instance_t _instance) { + + instance_ = _instance; +} + +eventgroup_t +subscribe_command_base::get_eventgroup() const { + + return eventgroup_; +} + +void +subscribe_command_base::set_eventgroup(eventgroup_t _eventgroup) { + + eventgroup_ = _eventgroup; +} + +major_version_t +subscribe_command_base::get_major() const { + + return major_; +} + +void +subscribe_command_base::set_major(major_version_t _major) { + + major_ = _major; +} + +event_t +subscribe_command_base::get_event() const { + + return event_; +} + +void +subscribe_command_base::set_event(event_t _event) { + + event_ = _event; +} + +pending_id_t +subscribe_command_base::get_pending_id() const { + + return pending_id_; +} + +void +subscribe_command_base::set_pending_id(pending_id_t _pending_id) { + + pending_id_ = _pending_id; +} + +void +subscribe_command_base::serialize(std::vector &_buffer, + error_e &_error) const { + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&_buffer[its_offset], &service_, sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&_buffer[its_offset], &instance_, sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&_buffer[its_offset], &eventgroup_, sizeof(eventgroup_)); + its_offset += sizeof(instance_); + _buffer[its_offset] = major_; + its_offset += sizeof(major_); + std::memcpy(&_buffer[its_offset], &event_, sizeof(event_)); + its_offset += sizeof(event_); + std::memcpy(&_buffer[its_offset], &pending_id_, sizeof(pending_id_)); +} + +void +subscribe_command_base::deserialize(const std::vector &_buffer, + error_e &_error) { + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + size_t its_offset(COMMAND_POSITION_PAYLOAD); + std::memcpy(&service_, &_buffer[its_offset], sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&instance_, &_buffer[its_offset], sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&eventgroup_, &_buffer[its_offset], sizeof(eventgroup_)); + its_offset += sizeof(eventgroup_); + major_ = _buffer[its_offset]; + its_offset += sizeof(major_); + std::memcpy(&event_, &_buffer[its_offset], sizeof(event_)); + its_offset += sizeof(event_); + std::memcpy(&pending_id_, &_buffer[its_offset], sizeof(pending_id_)); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/subscribe_nack_command.cpp b/implementation/protocol/src/subscribe_nack_command.cpp new file mode 100644 index 0000000..b009dad --- /dev/null +++ b/implementation/protocol/src/subscribe_nack_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/subscribe_nack_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +subscribe_nack_command::subscribe_nack_command() + : subscribe_ack_command_base(id_e::SUBSCRIBE_NACK_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/suspend_command.cpp b/implementation/protocol/src/suspend_command.cpp new file mode 100644 index 0000000..4f780f0 --- /dev/null +++ b/implementation/protocol/src/suspend_command.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/suspend_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +suspend_command::suspend_command() + : simple_command(id_e::SUSPEND_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/unregister_event_command.cpp b/implementation/protocol/src/unregister_event_command.cpp new file mode 100644 index 0000000..ff9813c --- /dev/null +++ b/implementation/protocol/src/unregister_event_command.cpp @@ -0,0 +1,135 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/unregister_event_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +unregister_event_command::unregister_event_command() + : command(id_e::UNREGISTER_EVENT_ID), + service_(ANY_SERVICE), + instance_(ANY_INSTANCE), + event_(ANY_EVENT), + is_provided_(false) { +} + +service_t +unregister_event_command::get_service() const { + + return service_; +} + +void +unregister_event_command::set_service(service_t _service) { + + service_ = _service; +} + +instance_t +unregister_event_command::get_instance() const { + + return instance_; +} + +void +unregister_event_command::set_instance(instance_t _instance) { + + instance_ = _instance; +} + +event_t +unregister_event_command::get_event() const { + + return event_; +} + +void +unregister_event_command::set_event(event_t _event) { + + event_ = _event; +} + + +bool +unregister_event_command::is_provided() const { + + return is_provided_; +} + +void +unregister_event_command::set_provided(bool _is_provided) { + + is_provided_ = _is_provided; +} + +void +unregister_event_command::serialize(std::vector &_buffer, error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(event_) + sizeof(is_provided_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&_buffer[its_offset], &service_, sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&_buffer[its_offset], &instance_, sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&_buffer[its_offset], &event_, sizeof(event_)); + its_offset += sizeof(event_); + _buffer[its_offset] = static_cast(is_provided_); +} + +void +unregister_event_command::deserialize(const std::vector &_buffer, error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(event_) + sizeof(is_provided_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&service_, &_buffer[its_offset], sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&instance_, &_buffer[its_offset], sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&event_, &_buffer[its_offset], sizeof(event_)); + its_offset += sizeof(event_); + is_provided_ = static_cast(_buffer[its_offset]); +} + +} // namespace protocol +} // namespace vsomeip_v3 diff --git a/implementation/protocol/src/unsubscribe_ack_command.cpp b/implementation/protocol/src/unsubscribe_ack_command.cpp new file mode 100644 index 0000000..ab7138d --- /dev/null +++ b/implementation/protocol/src/unsubscribe_ack_command.cpp @@ -0,0 +1,139 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/unsubscribe_ack_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +unsubscribe_ack_command::unsubscribe_ack_command() + : command(id_e::UNSUBSCRIBE_ACK_ID), + service_(ANY_SERVICE), + instance_(ANY_INSTANCE), + eventgroup_(0), + pending_id_(0) { +} + +service_t +unsubscribe_ack_command::get_service() const { + + return service_; +} + +void +unsubscribe_ack_command::set_service(service_t _service) { + + service_ = _service; +} + +instance_t +unsubscribe_ack_command::get_instance() const { + + return instance_; +} + +void +unsubscribe_ack_command::set_instance(instance_t _instance) { + + instance_ = _instance; +} + +eventgroup_t +unsubscribe_ack_command::get_eventgroup() const { + + return eventgroup_; +} + +void +unsubscribe_ack_command::set_eventgroup(eventgroup_t _eventgroup) { + + eventgroup_ = _eventgroup; +} + +pending_id_t +unsubscribe_ack_command::get_pending_id() const { + + return pending_id_; +} + +void +unsubscribe_ack_command::set_pending_id(pending_id_t _pending_id) { + + pending_id_ = _pending_id; +} + +void +unsubscribe_ack_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(pending_id_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&_buffer[its_offset], &service_, sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&_buffer[its_offset], &instance_, sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&_buffer[its_offset], &eventgroup_, sizeof(eventgroup_)); + its_offset += sizeof(eventgroup_); + std::memcpy(&_buffer[its_offset], &pending_id_, sizeof(pending_id_)); +} + +void +unsubscribe_ack_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(pending_id_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&service_, &_buffer[its_offset], sizeof(service_)); + its_offset += sizeof(service_); + std::memcpy(&instance_, &_buffer[its_offset], sizeof(instance_)); + its_offset += sizeof(instance_); + std::memcpy(&eventgroup_, &_buffer[its_offset], sizeof(eventgroup_)); + its_offset += sizeof(eventgroup_); + std::memcpy(&pending_id_, &_buffer[its_offset], sizeof(pending_id_)); + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/unsubscribe_command.cpp b/implementation/protocol/src/unsubscribe_command.cpp new file mode 100644 index 0000000..247b301 --- /dev/null +++ b/implementation/protocol/src/unsubscribe_command.cpp @@ -0,0 +1,64 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../include/unsubscribe_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +unsubscribe_command::unsubscribe_command() + : subscribe_command_base(id_e::UNSUBSCRIBE_ID) { +} + +void +unsubscribe_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(major_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // payload + subscribe_command_base::serialize(_buffer, _error); +} + +void +unsubscribe_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + size_t its_size(COMMAND_HEADER_SIZE + + sizeof(service_) + sizeof(instance_) + + sizeof(eventgroup_) + sizeof(major_) + + sizeof(event_) + sizeof(pending_id_)); + + if (its_size > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + subscribe_command_base::deserialize(_buffer, _error); +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/update_security_credentials_command.cpp b/implementation/protocol/src/update_security_credentials_command.cpp new file mode 100644 index 0000000..3e69653 --- /dev/null +++ b/implementation/protocol/src/update_security_credentials_command.cpp @@ -0,0 +1,103 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/update_security_credentials_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +update_security_credentials_command::update_security_credentials_command() + : command(id_e::UPDATE_SECURITY_CREDENTIALS_ID) { +} + +void +update_security_credentials_command::serialize(std::vector &_buffer, + error_e &_error) const { + + size_t its_size(COMMAND_HEADER_SIZE + + (credentials_.size() * (sizeof(uid_t) + sizeof(gid_t)))); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + for (const auto &c : credentials_) { + std::memcpy(&_buffer[its_offset], &c.first, sizeof(c.first)); + its_offset += sizeof(c.first); + std::memcpy(&_buffer[its_offset], &c.second, sizeof(c.second)); + its_offset += sizeof(c.second); + } +} + +void +update_security_credentials_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + if (COMMAND_HEADER_SIZE + size_ > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + size_t its_count(size_ / (sizeof(uid_t) + sizeof(gid_t))); + size_t its_offset(COMMAND_HEADER_SIZE); + + uid_t its_uid; + gid_t its_gid; + for (size_t i = 0; i < its_count; i++) { + std::memcpy(&its_uid, &_buffer[its_offset], sizeof(its_uid)); + its_offset += sizeof(its_uid); + std::memcpy(&its_gid, &_buffer[its_offset], sizeof(its_gid)); + its_offset += sizeof(its_gid); + + credentials_.emplace(std::make_pair(its_uid, its_gid)); + } +} + + +std::set > +update_security_credentials_command::get_credentials() const { + + return (credentials_); +} + +void +update_security_credentials_command::set_credentials( + const std::set > &_credentials) { + + credentials_ = _credentials; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/update_security_policy_command.cpp b/implementation/protocol/src/update_security_policy_command.cpp new file mode 100644 index 0000000..8ff79e2 --- /dev/null +++ b/implementation/protocol/src/update_security_policy_command.cpp @@ -0,0 +1,120 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../include/update_security_policy_command.hpp" +#include "../../security/include/policy.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +update_security_policy_command::update_security_policy_command( + bool _is_internal) + : command(_is_internal ? + id_e::UPDATE_SECURITY_POLICY_INT_ID : + id_e::UPDATE_SECURITY_POLICY_ID) { +} + +void +update_security_policy_command::serialize(std::vector &_buffer, + error_e &_error) const { + + std::vector its_policy_data; + if (policy_) { + if (policy_->serialize(its_policy_data)) { + _error = error_e::ERROR_UNKNOWN; + return; + } + } + + size_t its_size(COMMAND_HEADER_SIZE + sizeof(update_id_) + + its_policy_data.size()); + + if (its_size > std::numeric_limits::max()) { + + _error = error_e::ERROR_MAX_COMMAND_SIZE_EXCEEDED; + return; + } + + // resize buffer + _buffer.resize(its_size); + + // set size + size_ = static_cast(its_size - COMMAND_HEADER_SIZE); + + // serialize header + command::serialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // serialize payload + size_t its_offset(COMMAND_HEADER_SIZE); + std::memcpy(&_buffer[its_offset], &update_id_, sizeof(update_id_)); + its_offset += sizeof(update_id_); + std::memcpy(&_buffer[its_offset], + &its_policy_data[0], its_policy_data.size()); +} + +void +update_security_policy_command::deserialize(const std::vector &_buffer, + error_e &_error) { + + if (COMMAND_HEADER_SIZE + sizeof(update_id_) > _buffer.size()) { + + _error = error_e::ERROR_NOT_ENOUGH_BYTES; + return; + } + + // deserialize header + command::deserialize(_buffer, _error); + if (_error != error_e::ERROR_OK) + return; + + // deserialize payload + std::memcpy(&update_id_, &_buffer[COMMAND_POSITION_PAYLOAD], + sizeof(update_id_)); + policy_ = std::make_shared(); + const byte_t *its_policy_data + = &_buffer[COMMAND_HEADER_SIZE + sizeof(update_id_)]; + uint32_t its_policy_size + = uint32_t(_buffer.size() - COMMAND_HEADER_SIZE - sizeof(update_id_)); + + if (its_policy_size == 0 + || !policy_->deserialize(its_policy_data, its_policy_size)) { + + _error = error_e::ERROR_UNKNOWN; + policy_.reset(); + return; + } +} + +uint32_t +update_security_policy_command::get_update_id() const { + + return (update_id_); +} + +void +update_security_policy_command::set_update_id(uint32_t _update_id) { + + update_id_ = _update_id; +} + +std::shared_ptr +update_security_policy_command::get_policy() const { + + return (policy_); +} + +void +update_security_policy_command::set_policy( + const std::shared_ptr &_policy) { + + policy_ = _policy; +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/protocol/src/update_security_policy_response_command.cpp b/implementation/protocol/src/update_security_policy_response_command.cpp new file mode 100644 index 0000000..91573f0 --- /dev/null +++ b/implementation/protocol/src/update_security_policy_response_command.cpp @@ -0,0 +1,18 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/update_security_policy_response_command.hpp" + +namespace vsomeip_v3 { +namespace protocol { + +update_security_policy_response_command::update_security_policy_response_command() + : security_policy_response_command_base( + id_e::UPDATE_SECURITY_POLICY_RESPONSE_ID) { + +} + +} // namespace protocol +} // namespace vsomeip diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp index b22b6ed..97adb89 100644 --- a/implementation/routing/include/event.hpp +++ b/implementation/routing/include/event.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -13,7 +13,6 @@ #include #include -#include #include #include @@ -35,6 +34,8 @@ class message; class payload; class routing_manager; +struct debounce_filter_t; + class event : public std::enable_shared_from_this { public: @@ -52,16 +53,19 @@ public: event_t get_event() const; void set_event(event_t _event); - const std::shared_ptr get_payload() const; + std::shared_ptr get_payload() const; void set_payload(const std::shared_ptr &_payload, const client_t _client, bool _force); void set_payload(const std::shared_ptr &_payload, const client_t _client, - const std::shared_ptr& _target, bool _force); + const std::shared_ptr& _target); + + bool prepare_update_payload(const std::shared_ptr &_payload, + bool _force); + void update_payload(); - bool set_payload_dont_notify(const std::shared_ptr &_payload); bool set_payload_notify_pending(const std::shared_ptr &_payload); void set_payload(const std::shared_ptr &_payload, bool _force); @@ -90,20 +94,25 @@ public: void set_epsilon_change_function( const epsilon_change_func_t &_epsilon_change_func); - const std::set get_eventgroups() const; + std::set get_eventgroups() const; std::set get_eventgroups(client_t _client) const; void add_eventgroup(eventgroup_t _eventgroup); void set_eventgroups(const std::set &_eventgroups); void notify_one(client_t _client, const std::shared_ptr &_target); - void notify_one(client_t _client); + void notify_one(client_t _client, bool _force); - bool add_subscriber(eventgroup_t _eventgroup, client_t _client, bool _force); + bool add_subscriber(eventgroup_t _eventgroup, + const std::shared_ptr &_filter, + client_t _client, bool _force); void remove_subscriber(eventgroup_t _eventgroup, client_t _client); bool has_subscriber(eventgroup_t _eventgroup, client_t _client); std::set get_subscribers(); + std::set get_filtered_subscribers(bool _force); + std::set update_and_get_filtered_subscribers( + const std::shared_ptr &_payload, bool _force); VSOMEIP_EXPORT std::set get_subscribers(eventgroup_t _eventgroup); void clear_subscribers(); @@ -122,30 +131,34 @@ public: void remove_pending(const std::shared_ptr &_target); + void set_session(); + private: void update_cbk(boost::system::error_code const &_error); - void notify(); + void notify(bool _force); void notify(client_t _client, const std::shared_ptr &_target); void start_cycle(); void stop_cycle(); - bool compare(const std::shared_ptr &_lhs, + bool has_changed(const std::shared_ptr &_lhs, const std::shared_ptr &_rhs) const; - bool set_payload_helper(const std::shared_ptr &_payload, - bool _force); - void reset_payload(const std::shared_ptr &_payload); - - void notify_one_unlocked(client_t _client); + void notify_one_unlocked(client_t _client, bool _force); void notify_one_unlocked(client_t _client, const std::shared_ptr &_target); + bool prepare_update_payload_unlocked( + const std::shared_ptr &_payload, bool _force); + void update_payload_unlocked(); + private: routing_manager *routing_; mutable std::mutex mutex_; - std::shared_ptr message_; + + std::shared_ptr current_; + std::shared_ptr update_; std::atomic type_; @@ -172,6 +185,11 @@ private: std::atomic reliability_; std::set > pending_; + + std::mutex filters_mutex_; + std::map filters_; + std::mutex last_forwarded_mutex_; + std::map last_forwarded_; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/eventgroupinfo.hpp b/implementation/routing/include/eventgroupinfo.hpp index 8ec1ac6..1a5a1b9 100644 --- a/implementation/routing/include/eventgroupinfo.hpp +++ b/implementation/routing/include/eventgroupinfo.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -67,7 +67,7 @@ public: uint16_t _port); VSOMEIP_EXPORT bool is_sending_multicast() const; - VSOMEIP_EXPORT const std::set > get_events() const; + VSOMEIP_EXPORT std::set > get_events() const; VSOMEIP_EXPORT void add_event(const std::shared_ptr& _event); VSOMEIP_EXPORT void remove_event(const std::shared_ptr& _event); VSOMEIP_EXPORT reliability_type_e get_reliability() const; diff --git a/implementation/routing/include/function_types.hpp b/implementation/routing/include/function_types.hpp index 3f89c08..f74ff37 100644 --- a/implementation/routing/include/function_types.hpp +++ b/implementation/routing/include/function_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2018-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,9 +10,8 @@ namespace vsomeip_v3 { class remote_subscription; -typedef std::function< - void (const std::shared_ptr &_subscription) -> remote_subscription_callback_t; +using remote_subscription_callback_t = + std::function &_subscription)>; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/remote_subscription.hpp b/implementation/routing/include/remote_subscription.hpp index ff94d5b..f5bf2a2 100644 --- a/implementation/routing/include/remote_subscription.hpp +++ b/implementation/routing/include/remote_subscription.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2018-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -100,7 +100,6 @@ private: std::weak_ptr eventgroupinfo_; - major_version_t major_; ttl_t ttl_; std::uint16_t reserved_; std::uint8_t counter_; diff --git a/implementation/routing/include/routing_host.hpp b/implementation/routing/include/routing_host.hpp index 337e4a7..1decea3 100644 --- a/implementation/routing/include/routing_host.hpp +++ b/implementation/routing/include/routing_host.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,6 +11,7 @@ #include #include +#include #ifdef ANDROID #include "../../configuration/include/internal_android.hpp" @@ -28,15 +29,19 @@ public: virtual void on_message(const byte_t *_data, length_t _length, endpoint *_receiver, - const boost::asio::ip::address &_destination = - boost::asio::ip::address(), + bool _is_multicast = false, client_t _bound_client = VSOMEIP_ROUTING_CLIENT, - credentials_t _credentials = {ANY_UID, ANY_GID}, + const vsomeip_sec_client_t *_sec_client = nullptr, const boost::asio::ip::address &_remote_address = boost::asio::ip::address(), std::uint16_t _remote_port = 0) = 0; virtual client_t get_client() const = 0; + virtual void add_known_client(client_t _client, const std::string &_client_host) = 0; + + virtual void remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port) = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/routing_manager.hpp b/implementation/routing/include/routing_manager.hpp index fa0e675..6fa7693 100644 --- a/implementation/routing/include/routing_manager.hpp +++ b/implementation/routing/include/routing_manager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,11 +10,19 @@ #include #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include +#include #include #include +#include + #include "types.hpp" namespace vsomeip_v3 { @@ -30,10 +38,12 @@ public: virtual ~routing_manager() { } - virtual boost::asio::io_service & get_io() = 0; + virtual boost::asio::io_context &get_io() = 0; virtual client_t get_client() const = 0; - virtual void set_client(const client_t &_client) = 0; - virtual session_t get_session() = 0; +// virtual void set_client(const client_t &_client) = 0; + virtual session_t get_session(bool _is_request) = 0; + + virtual const vsomeip_sec_client_t *get_sec_client() const = 0; virtual void init() = 0; virtual void start() = 0; @@ -54,24 +64,29 @@ public: virtual void release_service(client_t _client, service_t _service, instance_t _instance) = 0; - virtual void subscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event) = 0; + virtual void subscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter) = 0; - virtual void unsubscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event) = 0; + virtual void unsubscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, event_t _event) = 0; - virtual bool send(client_t _client, std::shared_ptr _message) = 0; + virtual bool send(client_t _client, std::shared_ptr _message, + bool _force) = 0; virtual bool send(client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, bool _reliable, client_t _bound_client = VSOMEIP_ROUTING_CLIENT, - credentials_t _credentials = {ANY_UID, ANY_GID}, - uint8_t _status_check = 0, bool _sent_from_remote = false) = 0; + const vsomeip_sec_client_t *_sec_client = nullptr, + uint8_t _status_check = 0, + bool _sent_from_remote = false, + bool _force = true) = 0; virtual bool send_to(const client_t _client, const std::shared_ptr &_target, - std::shared_ptr) = 0; + std::shared_ptr _message) = 0; virtual bool send_to(const std::shared_ptr &_target, const byte_t *_data, uint32_t _size, instance_t _instance) = 0; diff --git a/implementation/routing/include/routing_manager_adapter.hpp b/implementation/routing/include/routing_manager_adapter.hpp index a2195ee..26154b0 100644 --- a/implementation/routing/include/routing_manager_adapter.hpp +++ b/implementation/routing/include/routing_manager_adapter.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/routing/include/routing_manager_base.hpp b/implementation/routing/include/routing_manager_base.hpp index 270f4c4..e4f9073 100644 --- a/implementation/routing/include/routing_manager_base.hpp +++ b/implementation/routing/include/routing_manager_base.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,16 +12,19 @@ #include #include +#include -#include "routing_host.hpp" -#include "routing_manager.hpp" -#include "routing_manager_host.hpp" #include "types.hpp" -#include "serviceinfo.hpp" #include "event.hpp" +#include "serviceinfo.hpp" +#include "routing_host.hpp" #include "eventgroupinfo.hpp" +#include "routing_manager.hpp" +#include "routing_manager_host.hpp" + #include "../../message/include/serializer.hpp" #include "../../message/include/deserializer.hpp" +#include "../../protocol/include/protocol.hpp" #include "../../configuration/include/configuration.hpp" #include "../../endpoints/include/endpoint_manager_base.hpp" @@ -43,10 +46,19 @@ public: routing_manager_base(routing_manager_host *_host); virtual ~routing_manager_base() = default; - virtual boost::asio::io_service & get_io(); + virtual boost::asio::io_context &get_io(); virtual client_t get_client() const; + + virtual std::string get_client_host() const; + virtual void set_client_host(const std::string &_client_host); virtual void set_client(const client_t &_client); - virtual session_t get_session(); + virtual session_t get_session(bool _is_request); + + virtual const vsomeip_sec_client_t *get_sec_client() const; + + virtual std::string get_env(client_t _client) const = 0; + + virtual bool is_routing_manager() const; virtual void init() = 0; void init(const std::shared_ptr& _endpoint_manager); @@ -83,11 +95,14 @@ public: virtual std::set> find_events(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const; - virtual void subscribe(client_t _client, uid_t _uid, gid_t _gid, + virtual void subscribe(client_t _client, + const vsomeip_sec_client_t *_sec_client, service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major, event_t _event); + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter); - virtual void unsubscribe(client_t _client, uid_t _uid, gid_t _gid, + virtual void unsubscribe(client_t _client, + const vsomeip_sec_client_t *_sec_client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event); @@ -102,23 +117,22 @@ public: #endif ); - virtual bool send(client_t _client, std::shared_ptr _message); + virtual bool send(client_t _client, std::shared_ptr _message, + bool _force); virtual bool send(client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, bool _reliable, - client_t _bound_client = VSOMEIP_ROUTING_CLIENT, - credentials_t _credentials = {ANY_UID, ANY_GID}, - uint8_t _status_check = 0, bool _sent_from_remote = false) = 0; + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + uint8_t _status_check, bool _sent_from_remote, + bool _force) = 0; // routing host -> will be implemented by routing_manager_impl/_proxy/ virtual void on_message(const byte_t *_data, length_t _length, - endpoint *_receiver, const boost::asio::ip::address &_destination - = boost::asio::ip::address(), client_t _bound_client = VSOMEIP_ROUTING_CLIENT, - credentials_t _credentials = {ANY_UID, ANY_GID}, - const boost::asio::ip::address &_remote_address = boost::asio::ip::address(), + endpoint *_receiver, bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port = 0) = 0; - virtual void set_routing_state(routing_state_e _routing_state) = 0; virtual routing_state_e get_routing_state(); @@ -138,6 +152,17 @@ public: std::shared_ptr find_event(service_t _service, instance_t _instance, event_t _event) const; + // address data for vsomeip routing via TCP + bool get_guest(client_t _client, boost::asio::ip::address &_address, + port_t &_port) const; + void add_guest(client_t _client, const boost::asio::ip::address &_address, + port_t _port); + void remove_guest(client_t _client); + + void remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port); + virtual void on_connect(const std::shared_ptr& _endpoint) = 0; virtual void on_disconnect(const std::shared_ptr& _endpoint) = 0; protected: @@ -150,10 +175,12 @@ protected: services_t get_services_remote() const; bool is_available(service_t _service, instance_t _instance, major_version_t _major); - void remove_local(client_t _client, bool _remove_uid); + void remove_local(client_t _client, bool _remove_sec_client); void remove_local(client_t _client, - const std::set>& _subscribed_eventgroups, - bool _remove_uid); + const std::set< + std::tuple + > &_subscribed_eventgroups, + bool _remove_sec_client); std::shared_ptr find_eventgroup(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const; @@ -163,15 +190,16 @@ protected: bool send_local_notification(client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, - bool _reliable = false, uint8_t _status_check = 0); + bool _reliable, uint8_t _status_check, bool _force); bool send_local( std::shared_ptr &_target, client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, - bool _reliable, uint8_t _command, uint8_t _status_check = 0) const; + bool _reliable, protocol::id_e _command, uint8_t _status_check) const; bool insert_subscription(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, event_t _event, client_t _client, + eventgroup_t _eventgroup, event_t _event, + const std::shared_ptr &_filter, client_t _client, std::set *_already_subscribed_events); std::shared_ptr get_serializer(); @@ -182,9 +210,10 @@ protected: void send_pending_subscriptions(service_t _service, instance_t _instance, major_version_t _major); - virtual void send_subscribe(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event) = 0; + virtual void send_subscribe(client_t _client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter) = 0; void remove_pending_subscription(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event); @@ -209,9 +238,11 @@ protected: bool is_response_allowed(client_t _sender, service_t _service, instance_t _instance, method_t _method); - bool is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client, + bool is_subscribe_to_any_event_allowed( + const vsomeip_sec_client_t *_sec_client, client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup); - void unsubscribe_all(service_t _service, instance_t _instance); + + void add_known_client(client_t _client, const std::string &_client_host); #ifdef VSOMEIP_ENABLE_COMPAT void set_incoming_subscription_state(client_t _client, service_t _service, instance_t _instance, @@ -227,12 +258,12 @@ protected: private: virtual bool create_placeholder_event_and_subscribe( service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, client_t _client) = 0; + event_t _event, const std::shared_ptr &_filter, + client_t _client) = 0; protected: routing_manager_host *host_; - boost::asio::io_service &io_; - std::atomic client_; + boost::asio::io_context &io_; std::shared_ptr configuration_; @@ -245,8 +276,9 @@ protected: std::condition_variable deserializer_condition_; mutable std::mutex local_services_mutex_; - typedef std::map>> local_services_map_t; + using local_services_map_t = + std::map>>; local_services_map_t local_services_; std::map > > local_services_history_; @@ -264,9 +296,6 @@ protected: std::mutex event_registration_mutex_; - std::mutex routing_state_mutex_; - routing_state_e routing_state_; - #ifdef USE_DLT std::shared_ptr tc_; #endif @@ -277,8 +306,8 @@ protected: eventgroup_t eventgroup_; major_version_t major_; event_t event_; - uid_t uid_; - gid_t gid_; + std::shared_ptr filter_; + vsomeip_sec_client_t sec_client_; bool operator<(const subscription_data_t &_other) const { return (service_ < _other.service_ @@ -300,13 +329,26 @@ protected: std::shared_ptr ep_mgr_; - std::uint32_t own_uid_; - std::uint32_t own_gid_; + mutable std::mutex known_clients_mutex_; + std::map known_clients_; + + mutable std::mutex env_mutex_; + std::string env_; + + std::mutex routing_state_mutex_; + routing_state_e routing_state_; private: services_t services_; mutable std::mutex services_mutex_; + mutable std::mutex guests_mutex_; + std::map + > guests_; + + std::mutex add_known_client_mutex_; + #ifdef VSOMEIP_ENABLE_COMPAT std::map +#include +#include +#include + +#include + +#include +#include + +#include "routing_manager_base.hpp" +#include "types.hpp" +#include "../../protocol/include/protocol.hpp" + +namespace vsomeip_v3 { + +class configuration; +class event; +#ifdef __linux__ +class netlink_connector; +#endif +class routing_manager_host; + +namespace protocol { + class offered_services_response_command; + class update_security_credentials_command; +} + +class routing_manager_client + : public routing_manager_base { +public: + routing_manager_client(routing_manager_host *_host, bool _client_side_logging, + const std::set > & _client_side_logging_filter); + virtual ~routing_manager_client(); + + void init(); + void start(); + void stop(); + + std::shared_ptr get_configuration() const; + std::string get_env(client_t _client) const; + std::string get_env_unlocked(client_t _client) const; + + bool offer_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor); + + void stop_offer_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor); + + void request_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor); + + void release_service(client_t _client, + service_t _service, instance_t _instance); + + void subscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter); + + void unsubscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, event_t _event); + + bool send(client_t _client, const byte_t *_data, uint32_t _size, + instance_t _instance, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + uint8_t _status_check, bool _sent_from_remote, + bool _force); + + bool send_to(const client_t _client, + const std::shared_ptr &_target, + std::shared_ptr _message); + + bool send_to(const std::shared_ptr &_target, + const byte_t *_data, uint32_t _size, instance_t _instance); + + void register_event(client_t _client, + service_t _service, instance_t _instance, + event_t _notifier, + const std::set &_eventgroups, + const event_type_e _type, + reliability_type_e _reliability, + std::chrono::milliseconds _cycle, bool _change_resets_cycle, + bool _update_on_change, + epsilon_change_func_t _epsilon_change_func, + bool _is_provided, bool _is_shadow, bool _is_cache_placeholder); + + void unregister_event(client_t _client, service_t _service, + instance_t _instance, event_t _notifier, bool _is_provided); + + void on_connect(const std::shared_ptr& _endpoint); + void on_disconnect(const std::shared_ptr& _endpoint); + void on_message(const byte_t *_data, length_t _size, endpoint *_receiver, + bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + const boost::asio::ip::address &_remote_address, + std::uint16_t _remote_port); + + void on_routing_info(const byte_t *_data, uint32_t _size); + + void register_client_error_handler(client_t _client, + const std::shared_ptr &_endpoint); + void handle_client_error(client_t _client); + + void on_offered_services_info(protocol::offered_services_response_command &_command); + + void send_get_offered_services_info(client_t _client, offer_type_e _offer_type); + +private: + void assign_client(); + void register_application(); + void deregister_application(); + + void reconnect(const std::map &_clients); + + void send_pong() const; + + void send_offer_service(client_t _client, service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor); + + void send_release_service(client_t _client, + service_t _service, instance_t _instance); + + void send_pending_event_registrations(client_t _client); + + void send_register_event(client_t _client, + service_t _service, instance_t _instance, + event_t _notifier, + const std::set &_eventgroups, + const event_type_e _type, reliability_type_e _reliability, + bool _is_provided, bool _is_cyclic); + + void send_subscribe(client_t _client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter); + + void send_subscribe_nack(client_t _subscriber, service_t _service, + instance_t _instance, eventgroup_t _eventgroup, event_t _event, + remote_subscription_id_t _id); + + void send_subscribe_ack(client_t _subscriber, service_t _service, + instance_t _instance, eventgroup_t _eventgroup, event_t _event, + remote_subscription_id_t _id); + + bool is_field(service_t _service, instance_t _instance, + event_t _event) const; + + void on_subscribe_nack(client_t _client, service_t _service, + instance_t _instance, eventgroup_t _eventgroup, event_t _event); + + void on_subscribe_ack(client_t _client, service_t _service, + instance_t _instance, eventgroup_t _eventgroup, event_t _event); + + void cache_event_payload(const std::shared_ptr &_message); + + void on_stop_offer_service(service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor); + + void send_pending_commands(); + + void init_receiver(); + + void notify_remote_initially(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, const std::set &_events_to_exclude); + + uint32_t get_remote_subscriber_count(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, bool _increment); + void clear_remote_subscriber_count(service_t _service, instance_t _instance); + + void assign_client_timeout_cbk(boost::system::error_code const &_error); + + void register_application_timeout_cbk(boost::system::error_code const &_error); + + void send_registered_ack(); + + void set_routing_state(routing_state_e _routing_state) { + (void)_routing_state; + }; + + bool is_client_known(client_t _client); + + bool create_placeholder_event_and_subscribe( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _notifier, const std::shared_ptr &_filter, + client_t _client); + + void request_debounce_timeout_cbk(boost::system::error_code const &_error); + + void send_request_services(const std::set &_requests); + + void send_unsubscribe_ack(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, remote_subscription_id_t _id); + + void resend_provided_event_registrations(); + void send_resend_provided_event_response(pending_remote_offer_id_t _id); + +#ifndef VSOMEIP_DISABLE_SECURITY + void send_update_security_policy_response(pending_security_update_id_t _update_id); + void send_remove_security_policy_response(pending_security_update_id_t _update_id); + void on_update_security_credentials(const protocol::update_security_credentials_command &_command); +#endif + void on_client_assign_ack(const client_t &_client); + + port_t get_routing_port(); + + void on_suspend(); + +#if defined(__linux__) || defined(ANDROID) + void on_net_state_change(bool _is_interface, const std::string &_name, bool _is_available); +#endif + +private: + + enum class inner_state_type_e : std::uint8_t { + ST_REGISTERED = 0x0, + ST_DEREGISTERED = 0x1, + ST_REGISTERING = 0x2, + ST_ASSIGNING = 0x3, + ST_ASSIGNED = 0x4 + }; + + std::atomic is_connected_; + std::atomic is_started_; + inner_state_type_e state_; + + std::shared_ptr sender_; // --> stub + std::shared_ptr receiver_; // --> from everybody + + std::set pending_offers_; + std::set requests_; + std::set requests_to_debounce_; + + struct event_data_t { + service_t service_; + instance_t instance_; + event_t notifier_; + event_type_e type_; + reliability_type_e reliability_; + bool is_provided_; + bool is_cyclic_; + std::set eventgroups_; + + bool operator<(const event_data_t &_other) const { + return std::tie(service_, instance_, notifier_, + type_, reliability_, is_provided_, is_cyclic_, eventgroups_) + < std::tie(_other.service_, _other.instance_, + _other.notifier_, _other.type_, _other.reliability_, + _other.is_provided_, _other.is_cyclic_, _other.eventgroups_); + } + }; + std::set pending_event_registrations_; + + std::map> pending_incoming_subscriptions_; + std::recursive_mutex incoming_subscriptions_mutex_; + + std::mutex state_mutex_; + std::condition_variable state_condition_; + + std::map > > remote_subscriber_count_; + std::mutex remote_subscriber_count_mutex_; + + mutable std::mutex sender_mutex_; + + boost::asio::steady_timer register_application_timer_; + + std::mutex request_timer_mutex_; + boost::asio::steady_timer request_debounce_timer_; + bool request_debounce_timer_running_; + + const bool client_side_logging_; + const std::set > client_side_logging_filter_; + + std::mutex stop_mutex_; + +#if defined(__linux__) || defined(ANDROID) + std::shared_ptr local_link_connector_; + bool is_local_link_available_; +#endif +}; + +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_ROUTING_MANAGER_CLIENT_HPP_ diff --git a/implementation/routing/include/routing_manager_host.hpp b/implementation/routing/include/routing_manager_host.hpp index 69133e2..18a74af 100644 --- a/implementation/routing/include/routing_manager_host.hpp +++ b/implementation/routing/include/routing_manager_host.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,9 +8,15 @@ #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include +#include namespace vsomeip_v3 { @@ -24,22 +30,30 @@ public: virtual client_t get_client() const = 0; virtual void set_client(const client_t &_client) = 0; - virtual session_t get_session() = 0; + virtual session_t get_session(bool _is_request) = 0; + + virtual const vsomeip_sec_client_t *get_sec_client() const = 0; + virtual const std::string & get_name() const = 0; virtual std::shared_ptr get_configuration() const = 0; - virtual boost::asio::io_service & get_io() = 0; + virtual boost::asio::io_context &get_io() = 0; virtual void on_availability(service_t _service, instance_t _instance, - bool _is_available, major_version_t _major = DEFAULT_MAJOR, minor_version_t _minor = DEFAULT_MINOR) = 0; + availability_state_e _state, + major_version_t _major = DEFAULT_MAJOR, + minor_version_t _minor = DEFAULT_MINOR) = 0; virtual void on_state(state_type_e _state) = 0; virtual void on_message(std::shared_ptr &&_message) = 0; virtual void on_subscription(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, client_t _client, uid_t _uid, gid_t _gid, bool _subscribed, - std::function _accepted_cb) = 0; + eventgroup_t _eventgroup, + client_t _client, const vsomeip_sec_client_t *_sec_client, + const std::string &_env, bool _subscribed, + const std::function &_accepted_cb) = 0; virtual void on_subscription_status(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, uint16_t _error) = 0; virtual void send(std::shared_ptr _message) = 0; - virtual void on_offered_services_info(std::vector> &_services) = 0; + virtual void on_offered_services_info( + std::vector> &_services) = 0; virtual bool is_routing() const = 0; }; diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index 3fd6eed..3c105c2 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -14,7 +14,6 @@ #include #include -#include #include #include @@ -36,7 +35,6 @@ class deserializer; class eventgroupinfo; class routing_manager_host; class routing_manager_stub; -class servicegroup; class serializer; class service_endpoint; @@ -55,8 +53,13 @@ public: routing_manager_impl(routing_manager_host *_host); ~routing_manager_impl(); - boost::asio::io_service & get_io(); + boost::asio::io_context &get_io(); client_t get_client() const; + const vsomeip_sec_client_t *get_sec_client() const; + std::string get_client_host() const; + void set_client_host(const std::string &_client_host); + + bool is_routing_manager() const; void init(); void start(); @@ -77,21 +80,23 @@ public: void release_service(client_t _client, service_t _service, instance_t _instance); - void subscribe(client_t _client, uid_t _uid, gid_t _gid, + void subscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major, event_t _event); + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter); - void unsubscribe(client_t _client, uid_t _uid, gid_t _gid, + void unsubscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event); - bool send(client_t _client, std::shared_ptr _message); + bool send(client_t _client, std::shared_ptr _message, + bool _force); bool send(client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, bool _reliable, - client_t _bound_client = VSOMEIP_ROUTING_CLIENT, - credentials_t _credentials = {ANY_UID, ANY_GID}, - uint8_t _status_check = 0, bool _sent_from_remote = false); + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + uint8_t _status_check, bool _sent_from_remote, + bool _force); bool send_to(const client_t _client, const std::shared_ptr &_target, @@ -120,7 +125,7 @@ public: event_t _notifier, const std::set &_eventgroups, event_type_e _type, reliability_type_e _reliability, - bool _is_provided); + bool _is_provided, bool _is_cyclic); void unregister_shadow_event(client_t _client, service_t _service, instance_t _instance, event_t _event, @@ -140,7 +145,7 @@ public: void on_subscribe_nack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, - remote_subscription_id_t _id, bool _simulated); + remote_subscription_id_t _id); // interface to stub @@ -161,7 +166,7 @@ public: major_version_t _major, minor_version_t _minor); void on_availability(service_t _service, instance_t _instance, - bool _is_available, + availability_state_e _state, major_version_t _major, minor_version_t _minor); void on_pong(client_t _client); @@ -178,13 +183,13 @@ public: void on_disconnect(const std::shared_ptr& _endpoint); void on_message(const byte_t *_data, length_t _size, endpoint *_receiver, - const boost::asio::ip::address &_destination, - client_t _bound_client, credentials_t _credentials, - const boost::asio::ip::address &_remote_address, - std::uint16_t _remote_port); + bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + const boost::asio::ip::address &_remote_address, + std::uint16_t _remote_port); bool on_message(service_t _service, instance_t _instance, const byte_t *_data, length_t _size, bool _reliable, - client_t _bound_client, credentials_t _credentials, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, uint8_t _check_status = 0, bool _is_from_remote = false); void on_notification(client_t _client, service_t _service, @@ -199,8 +204,6 @@ public: bool _magic_cookies_enabled); // interface "service_discovery_host" - typedef std::map > servicegroups_t; - const servicegroups_t & get_servicegroups() const; std::shared_ptr find_eventgroup(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const; services_t get_offered_services() const; @@ -285,15 +288,27 @@ public: void on_resend_provided_events_response(pending_remote_offer_id_t _id); client_t find_local_client(service_t _service, instance_t _instance); std::set find_local_clients(service_t _service, instance_t _instance); - bool is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client, + bool is_subscribe_to_any_event_allowed( + const vsomeip_sec_client_t *_sec_client, client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup); +#ifndef VSOMEIP_DISABLE_SECURITY bool update_security_policy_configuration(uint32_t _uid, uint32_t _gid, const std::shared_ptr &_policy, const std::shared_ptr &_payload, const security_update_handler_t &_handler); bool remove_security_policy_configuration(uint32_t _uid, uint32_t _gid, const security_update_handler_t &_handler); +#endif + + void add_known_client(client_t _client, const std::string &_client_host); + + void register_message_acceptance_handler( + const message_acceptance_handler_t &_handler); + + void remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port); private: bool offer_service(client_t _client, @@ -307,12 +322,12 @@ private: bool _must_queue); bool deliver_message(const byte_t *_data, length_t _size, - instance_t _instance, bool _reliable, client_t _bound_client, - credentials_t _credentials, + instance_t _instance, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, uint8_t _status_check = 0, bool _is_from_remote = false); bool deliver_notification(service_t _service, instance_t _instance, - const byte_t *_data, length_t _length, bool _reliable, client_t _bound_client, - credentials_t _credentials, + const byte_t *_data, length_t _length, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, uint8_t _status_check = 0, bool _is_from_remote = false); @@ -351,38 +366,49 @@ private: bool handle_local_offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major,minor_version_t _minor); - void send_subscribe(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event); + void send_subscribe(client_t _client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter); void on_net_interface_or_route_state_changed(bool _is_interface, - std::string _if, + const std::string &_if, bool _available); void start_ip_routing(); - void requested_service_add(client_t _client, service_t _service, + void add_requested_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor); - void requested_service_remove(client_t _client, service_t _service, - instance_t _instance); - - void call_sd_endpoint_connected(const boost::system::error_code& _error, - service_t _service, instance_t _instance, - const std::shared_ptr& _endpoint, - std::shared_ptr _timer); + void remove_requested_service(client_t _client, service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor); + std::vector> get_requested_services(client_t _client); + std::set get_requesters(service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor); + std::set get_requesters_unlocked(service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor); + bool has_requester_unlocked(service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor); + + void call_sd_endpoint_connected(const boost::system::error_code &_error, + service_t _service, instance_t _instance, + const std::shared_ptr &_endpoint, + std::shared_ptr _timer); - bool create_placeholder_event_and_subscribe(service_t _service, - instance_t _instance, - eventgroup_t _eventgroup, - event_t _event, - client_t _client); + bool create_placeholder_event_and_subscribe( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _event, const std::shared_ptr &_filter, + client_t _client); void handle_subscription_state(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event); - void memory_log_timer_cbk(boost::system::error_code const & _error); - void status_log_timer_cbk(boost::system::error_code const & _error); + void memory_log_timer_cbk(boost::system::error_code const &_error); + void status_log_timer_cbk(boost::system::error_code const &_error); void send_subscription(const client_t _offering_client, const service_t _service, const instance_t _instance, @@ -416,25 +442,48 @@ private: bool is_last_stop_callback(const uint32_t _callback_id); + std::string get_env(client_t _client) const; + std::string get_env_unlocked(client_t _client) const; + bool insert_event_statistics(service_t _service, instance_t _instance, method_t _method, length_t _length); void statistics_log_timer_cbk(boost::system::error_code const & _error); + bool get_guest(client_t _client, boost::asio::ip::address &_address, + port_t &_port) const; + void add_guest(client_t _client, const boost::asio::ip::address &_address, + port_t _port); + void remove_guest(client_t _client); + void send_suspend() const; + void clear_local_services(); + + bool is_acl_message_allowed(endpoint *_receiver, + service_t _service, instance_t _instance, + const boost::asio::ip::address &_remote_address) const; + private: std::shared_ptr stub_; std::shared_ptr discovery_; std::mutex requested_services_mutex_; - std::map>>>> requested_services_; + std::map > + > + > + > requested_services_; std::mutex remote_subscribers_mutex_; - std::map>>>> remote_subscribers_; + std::map > + > + > + > remote_subscribers_; std::shared_ptr sd_info_; @@ -446,7 +495,7 @@ private: bool routing_running_; std::mutex pending_sd_offers_mutex_; std::vector> pending_sd_offers_; -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) std::shared_ptr netlink_connector_; #endif @@ -503,6 +552,8 @@ private: // synchronize update_remote_subscription() and send_(un)subscription() std::mutex update_remote_subscription_mutex_; + + message_acceptance_handler_t message_acceptance_handler_; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_proxy.hpp deleted file mode 100644 index 2b5335a..0000000 --- a/implementation/routing/include/routing_manager_proxy.hpp +++ /dev/null @@ -1,267 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef VSOMEIP_V3_ROUTING_MANAGER_PROXY_HPP -#define VSOMEIP_V3_ROUTING_MANAGER_PROXY_HPP - -#include -#include -#include -#include - -#include -#include - -#include "routing_manager_base.hpp" -#include "types.hpp" -#include -#include - -namespace vsomeip_v3 { - -class configuration; -class event; -class routing_manager_host; - -class routing_manager_proxy: public routing_manager_base { -public: - routing_manager_proxy(routing_manager_host *_host, bool _client_side_logging, - const std::set > & _client_side_logging_filter); - virtual ~routing_manager_proxy(); - - void init(); - void start(); - void stop(); - - std::shared_ptr get_configuration() const; - - bool offer_service(client_t _client, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor); - - void stop_offer_service(client_t _client, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor); - - void request_service(client_t _client, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor); - - void release_service(client_t _client, - service_t _service, instance_t _instance); - - void subscribe(client_t _client, uid_t _uid, gid_t _gid, - service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major, - event_t _event); - - void unsubscribe(client_t _client, uid_t _uid, gid_t _gid, - service_t _service, instance_t _instance, - eventgroup_t _eventgroup, event_t _event); - - bool send(client_t _client, const byte_t *_data, uint32_t _size, - instance_t _instance, bool _reliable, - client_t _bound_client = VSOMEIP_ROUTING_CLIENT, - credentials_t _credentials = {ANY_UID, ANY_GID}, - uint8_t _status_check = 0, bool _sent_from_remote = false); - - bool send_to(const client_t _client, - const std::shared_ptr &_target, - std::shared_ptr _message); - - bool send_to(const std::shared_ptr &_target, - const byte_t *_data, uint32_t _size, instance_t _instance); - - void register_event(client_t _client, - service_t _service, instance_t _instance, - event_t _notifier, - const std::set &_eventgroups, - const event_type_e _type, - reliability_type_e _reliability, - std::chrono::milliseconds _cycle, bool _change_resets_cycle, - bool _update_on_change, - epsilon_change_func_t _epsilon_change_func, - bool _is_provided, bool _is_shadow, bool _is_cache_placeholder); - - void unregister_event(client_t _client, service_t _service, - instance_t _instance, event_t _notifier, bool _is_provided); - - void on_connect(const std::shared_ptr& _endpoint); - void on_disconnect(const std::shared_ptr& _endpoint); - void on_message(const byte_t *_data, length_t _size, endpoint *_receiver, - const boost::asio::ip::address &_destination, - client_t _bound_client, - credentials_t _credentials, - const boost::asio::ip::address &_remote_address, - std::uint16_t _remote_port); - - void on_routing_info(const byte_t *_data, uint32_t _size); - - void register_client_error_handler(client_t _client, - const std::shared_ptr &_endpoint); - void handle_client_error(client_t _client); - - void on_offered_services_info(const byte_t *_data, uint32_t _size); - - void send_get_offered_services_info(client_t _client, offer_type_e _offer_type); - -private: - void assign_client(); - void register_application(); - void deregister_application(); - - void reconnect(const std::unordered_set &_clients); - - void send_pong() const; - void send_offer_service(client_t _client, service_t _service, - instance_t _instance, major_version_t _major, - minor_version_t _minor); - void send_release_service(client_t _client, - service_t _service, instance_t _instance); - void send_register_event(client_t _client, - service_t _service, instance_t _instance, - event_t _notifier, - const std::set &_eventgroups, - const event_type_e _type, reliability_type_e _reliability, - bool _is_provided); - void send_subscribe(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event); - - void send_subscribe_nack(client_t _subscriber, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event, - remote_subscription_id_t _id); - - void send_subscribe_ack(client_t _subscriber, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event, - remote_subscription_id_t _id); - - bool is_field(service_t _service, instance_t _instance, - event_t _event) const; - - void on_subscribe_nack(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event); - - void on_subscribe_ack(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event); - - void cache_event_payload(const std::shared_ptr &_message); - - void on_stop_offer_service(service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor); - - void send_pending_commands(); - - void init_receiver(); - - void notify_remote_initially(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, const std::set &_events_to_exclude); - - uint32_t get_remote_subscriber_count(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, bool _increment); - void clear_remote_subscriber_count(service_t _service, instance_t _instance); - - void assign_client_timeout_cbk(boost::system::error_code const &_error); - - void register_application_timeout_cbk(boost::system::error_code const &_error); - - void send_registered_ack(); - - void set_routing_state(routing_state_e _routing_state) { - (void)_routing_state; - }; - - bool is_client_known(client_t _client); - - bool create_placeholder_event_and_subscribe( - service_t _service, instance_t _instance, - eventgroup_t _eventgroup, event_t _notifier, client_t _client); - - void request_debounce_timeout_cbk(boost::system::error_code const &_error); - - void send_request_services(std::set& _requests); - - void send_unsubscribe_ack(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, remote_subscription_id_t _id); - - void resend_provided_event_registrations(); - void send_resend_provided_event_response(pending_remote_offer_id_t _id); - - void send_update_security_policy_response(pending_security_update_id_t _update_id); - void send_remove_security_policy_response(pending_security_update_id_t _update_id); - void on_update_security_credentials(const byte_t *_data, uint32_t _size); - void on_client_assign_ack(const client_t &_client); - - void on_suspend(); - -private: - enum class inner_state_type_e : std::uint8_t { - ST_REGISTERED = 0x0, - ST_DEREGISTERED = 0x1, - ST_REGISTERING = 0x2, - ST_ASSIGNING = 0x3, - ST_ASSIGNED = 0x4 - }; - - std::atomic is_connected_; - std::atomic is_started_; - inner_state_type_e state_; - - std::shared_ptr sender_; // --> stub - std::shared_ptr receiver_; // --> from everybody - - std::mutex known_clients_mutex_; - std::unordered_set known_clients_; - - std::set pending_offers_; - std::set requests_; - std::set requests_to_debounce_; - - struct event_data_t { - service_t service_; - instance_t instance_; - event_t notifier_; - event_type_e type_; - reliability_type_e reliability_; - bool is_provided_; - std::set eventgroups_; - - bool operator<(const event_data_t &_other) const { - return std::tie(service_, instance_, notifier_, - type_, reliability_, is_provided_, eventgroups_) - < std::tie(_other.service_, _other.instance_, - _other.notifier_, _other.type_, _other.reliability_, - _other.is_provided_, _other.eventgroups_); - } - }; - std::set pending_event_registrations_; - - std::map> pending_incoming_subscripitons_; - std::recursive_mutex incoming_subscriptions_mutex_; - - std::mutex state_mutex_; - std::condition_variable state_condition_; - - std::map > > remote_subscriber_count_; - std::mutex remote_subscriber_count_mutex_; - - mutable std::mutex sender_mutex_; - - boost::asio::steady_timer register_application_timer_; - - std::mutex request_timer_mutex_; - boost::asio::steady_timer request_debounce_timer_; - bool request_debounce_timer_running_; - - const bool client_side_logging_; - const std::set > client_side_logging_filter_; - - std::mutex stop_mutex_; -}; - -} // namespace vsomeip_v3 - -#endif // VSOMEIP_V3_ROUTING_MANAGER_PROXY_HPP_ diff --git a/implementation/routing/include/routing_manager_stub.hpp b/implementation/routing/include/routing_manager_stub.hpp index aa5796e..4209eec 100644 --- a/implementation/routing/include/routing_manager_stub.hpp +++ b/implementation/routing/include/routing_manager_stub.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -16,22 +16,34 @@ #include #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include #include - -#include "../../endpoints/include/endpoint_host.hpp" -#include "../include/routing_host.hpp" +#include #include "types.hpp" +#include "../include/routing_host.hpp" +#include "../../endpoints/include/endpoint_host.hpp" +#include "../../protocol/include/protocol.hpp" +#include "../../protocol/include/routing_info_entry.hpp" namespace vsomeip_v3 { class configuration; -struct policy; +#if defined(__linux__) || defined(ANDROID) +class netlink_connector; +#endif // __linux__ || ANDROID class routing_manager_stub_host; +struct debounce_filter_t; +struct policy; + class routing_manager_stub: public routing_host, public std::enable_shared_from_this { public: @@ -44,10 +56,9 @@ public: void start(); void stop(); - void on_message(const byte_t *_data, length_t _size, endpoint *_receiver, - const boost::asio::ip::address &_destination, - client_t _bound_client, - credentials_t _credentials, + void on_message(const byte_t *_data, length_t _size, + endpoint *_receiver, bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port); @@ -56,9 +67,11 @@ public: void on_stop_offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor); - bool send_subscribe(const std::shared_ptr& _target, - client_t _client, service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major, event_t _event, + bool send_subscribe( + const std::shared_ptr &_target, client_t _client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter, remote_subscription_id_t _id); bool send_unsubscribe(const std::shared_ptr& _target, @@ -85,16 +98,18 @@ public: bool send_ping(client_t _client); bool is_registered(client_t _client) const; client_t get_client() const; - void handle_credentials(const client_t _client, std::set& _requests); - void handle_requests(const client_t _client, std::set& _requests); + void handle_credentials(const client_t _client, std::set &_requests); + void handle_requests(const client_t _client, std::set &_requests); - void update_registration(client_t _client, registration_type_e _type); + void update_registration(client_t _client, registration_type_e _type, + const boost::asio::ip::address &_address, port_t _port); void print_endpoint_status() const; bool send_provided_event_resend_request(client_t _client, pending_remote_offer_id_t _id); +#ifndef VSOMEIP_DISABLE_SECURITY bool update_security_policy_configuration(uint32_t _uid, uint32_t _gid, const std::shared_ptr &_policy, const std::shared_ptr &_payload, @@ -119,23 +134,29 @@ public: bool add_requester_policies(uid_t _uid, gid_t _gid, const std::set > &_policies); void remove_requester_policies(uid_t _uid, gid_t _gid); +#endif // !VSOMEIP_DISABLE_SECURITY + + void add_known_client(client_t _client, const std::string &_client_host); void send_suspend() const; + void remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port); + private: void broadcast(const std::vector &_command) const; void on_register_application(client_t _client); void on_deregister_application(client_t _client); + void on_offered_service_request(client_t _client, offer_type_e _offer_type); + void distribute_credentials(client_t _hoster, service_t _service, instance_t _instance); - void inform_provider(client_t _hoster, service_t _service, - instance_t _instance, major_version_t _major, minor_version_t _minor, - routing_info_entry_e _entry); void inform_requesters(client_t _hoster, service_t _service, instance_t _instance, major_version_t _major, - minor_version_t _minor, routing_info_entry_e _entry, + minor_version_t _minor, protocol::routing_info_entry_type_e _entry, bool _inform_service); void broadcast_ping() const; @@ -151,27 +172,35 @@ private: (void)_routing_state; }; - bool is_already_connected(client_t _source, client_t _sink); - void create_client_routing_info(const client_t _target); - void insert_client_routing_info(client_t _target, routing_info_entry_e _entry, - client_t _client, service_t _service = ANY_SERVICE, - instance_t _instance = ANY_INSTANCE, - major_version_t _major = ANY_MAJOR, - minor_version_t _minor = ANY_MINOR); - void send_client_routing_info(const client_t _target); - - void create_offered_services_info(const client_t _target); - void insert_offered_services_info(client_t _target, - routing_info_entry_e _entry, - service_t _service, - instance_t _instance, - major_version_t _major, - minor_version_t _minor); - void send_offered_services_info(const client_t _target); - - void create_client_credentials_info(const client_t _target); - void insert_client_credentials_info(client_t _target, std::set> _credentials); - void send_client_credentials_info(const client_t _target); + inline bool is_connected(client_t _source, client_t _sink) const { + + auto find_source = connection_matrix_.find(_source); + if (find_source != connection_matrix_.end()) + return (find_source->second.find(_sink) + != find_source->second.end()); + + return (false); + } + inline void add_connection(client_t _source, client_t _sink) { + + connection_matrix_[_source].insert(_sink); + } + inline void remove_connection(client_t _source, client_t _sink) { + + auto find_source = connection_matrix_.find(_source); + if (find_source != connection_matrix_.end()) + find_source->second.erase(_sink); + } + inline void remove_source(client_t _source) { + + connection_matrix_.erase(_source); + } + + void send_client_routing_info(const client_t _target, + protocol::routing_info_entry &_entry); + void send_client_routing_info(const client_t _target, + std::vector &&_entries); + void send_client_credentials(client_t _target, std::set> &_credentials); void on_client_id_timer_expired(boost::system::error_code const &_error); @@ -199,13 +228,17 @@ private: void add_pending_security_update_handler( pending_security_update_id_t _id, - security_update_handler_t _handler); + const security_update_handler_t &_handler); void add_pending_security_update_timer( pending_security_update_id_t _id); +#if defined(__linux__) || defined(ANDROID) + void on_net_state_change(bool _is_interface, const std::string &_name, bool _is_available); +#endif + private: routing_manager_stub_host *host_; - boost::asio::io_service &io_; + boost::asio::io_context &io_; std::mutex watchdog_timer_mutex_; boost::asio::steady_timer watchdog_timer_; @@ -213,7 +246,8 @@ private: std::set used_client_ids_; std::mutex used_client_ids_mutex_; - std::shared_ptr endpoint_; + std::shared_ptr root_; // Routing manager endpoint + std::shared_ptr local_receiver_; std::mutex local_receiver_mutex_; @@ -229,8 +263,8 @@ private: std::condition_variable client_registration_condition_; std::map> pending_client_registrations_; + std::map > internal_client_ports_; const std::uint32_t max_local_message_size_; - static const std::vector its_ping_; const std::chrono::milliseconds configured_watchdog_timeout_; boost::asio::steady_timer pinged_clients_timer_; std::mutex pinged_clients_mutex_; @@ -239,10 +273,6 @@ private: std::map > > > service_requests_; std::map> connection_matrix_; - std::map> client_routing_info_; - std::map> offered_services_info_; - std::map> client_credentials_info_; - std::mutex pending_security_updates_mutex_; pending_security_update_id_t pending_security_update_id_; std::map> pending_security_updates_; @@ -262,6 +292,14 @@ private: std::set > > > requester_policies_; + + +#if defined(__linux__) || defined(ANDROID) + // netlink connector for internal network + // (replacement for Unix Domain Sockets if configured) + std::shared_ptr local_link_connector_; + bool is_local_link_available_; +#endif }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/routing_manager_stub_host.hpp b/implementation/routing/include/routing_manager_stub_host.hpp index 6ad0ab1..c55dd86 100644 --- a/implementation/routing/include/routing_manager_stub_host.hpp +++ b/implementation/routing/include/routing_manager_stub_host.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,9 +6,16 @@ #ifndef VSOMEIP_V3_ROUTING_MANAGER_STUB_HOST_ #define VSOMEIP_V3_ROUTING_MANAGER_STUB_HOST_ -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include +#include + #include "types.hpp" namespace vsomeip_v3 { @@ -28,57 +35,59 @@ public: instance_t _instance, major_version_t _major, minor_version_t _minor, bool _must_queue = true) = 0; - virtual void request_service(client_t _client, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor) = 0; + virtual void request_service(client_t _client, service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor) = 0; - virtual void release_service(client_t _client, - service_t _service, instance_t _instance) = 0; + virtual void release_service(client_t _client, service_t _service, + instance_t _instance) = 0; - virtual void register_shadow_event(client_t _client, - service_t _service, instance_t _instance, - event_t _notifier, - const std::set &_eventgroups, - event_type_e _type, reliability_type_e _reliability, - bool _is_provided) = 0; + virtual void register_shadow_event(client_t _client, service_t _service, + instance_t _instance, event_t _notifier, + const std::set &_eventgroups, event_type_e _type, + reliability_type_e _reliability, bool _is_provided, + bool _is_cyclic) = 0; virtual void unregister_shadow_event(client_t _client, service_t _service, instance_t _instance, event_t _event, bool _is_provided) = 0; - virtual void subscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event) = 0; + virtual void subscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + major_version_t _major, event_t _event, + const std::shared_ptr &_filter) = 0; virtual void on_subscribe_nack(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event, - remote_subscription_id_t _subscription_id, bool _simulated) = 0; + instance_t _instance, eventgroup_t _eventgroup, event_t _event, + remote_subscription_id_t _subscription_id) = 0; virtual void on_subscribe_ack(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event, - remote_subscription_id_t _subscription_id) = 0; + instance_t _instance, eventgroup_t _eventgroup, event_t _event, + remote_subscription_id_t _subscription_id) = 0; - virtual void unsubscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event) = 0; + virtual void unsubscribe(client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _event) = 0; virtual void on_unsubscribe_ack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, remote_subscription_id_t _unsubscription_id) = 0; virtual bool on_message(service_t _service, instance_t _instance, - const byte_t *_data, length_t _size, bool _reliable, client_t _bound_client, - credentials_t _credentials, + const byte_t *_data, length_t _size, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, uint8_t _status_check = 0, bool _is_from_remote = false) = 0; - virtual void on_notification(client_t _client, - service_t _service, instance_t _instance, - const byte_t *_data, length_t _size, bool _notify_one = false) = 0; + virtual void on_notification(client_t _client, service_t _service, + instance_t _instance, const byte_t *_data, length_t _size, + bool _notify_one = false) = 0; virtual void on_stop_offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) = 0; virtual void on_availability(service_t _service, instance_t _instance, - bool _is_available, major_version_t _major, minor_version_t _minor) = 0; + availability_state_e _state, major_version_t _major, + minor_version_t _minor) = 0; virtual std::shared_ptr find_local(client_t _client) = 0; @@ -86,8 +95,9 @@ public: client_t _client) = 0; virtual void remove_local(client_t _client, bool _remove_local) = 0; - virtual boost::asio::io_service & get_io() = 0; + virtual boost::asio::io_context& get_io() = 0; virtual client_t get_client() const = 0; + virtual const vsomeip_sec_client_t *get_sec_client() const = 0; virtual void on_pong(client_t _client) = 0; @@ -95,14 +105,32 @@ public: virtual std::shared_ptr get_endpoint_manager() const = 0; - virtual void on_resend_provided_events_response(pending_remote_offer_id_t _id) = 0; + virtual void on_resend_provided_events_response( + pending_remote_offer_id_t _id) = 0; + + virtual client_t find_local_client(service_t _service, + instance_t _instance) = 0; + + virtual std::set find_local_clients(service_t _service, + instance_t _instance) = 0; + + virtual bool is_subscribe_to_any_event_allowed( + const vsomeip_sec_client_t *_sec_client, + client_t _client, service_t _service, instance_t _instance, + eventgroup_t _eventgroup) = 0; + + virtual void add_known_client(client_t _client, + const std::string &_client_host) = 0; - virtual client_t find_local_client(service_t _service, instance_t _instance) = 0; + virtual void set_client_host(const std::string &_client_host) = 0; - virtual std::set find_local_clients(service_t _service, instance_t _instance) = 0; + virtual bool get_guest(client_t _client, + boost::asio::ip::address &_address, port_t &_port) const = 0; + virtual void add_guest(client_t _client, + const boost::asio::ip::address &_address, port_t _port) = 0; + virtual void remove_guest(client_t _client) = 0; - virtual bool is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client, - service_t _service, instance_t _instance, eventgroup_t _eventgroup) = 0; + virtual void clear_local_services() = 0; }; } // namespace vsomeip_v3 diff --git a/implementation/routing/include/serviceinfo.hpp b/implementation/routing/include/serviceinfo.hpp index a405cf0..5ea4c18 100644 --- a/implementation/routing/include/serviceinfo.hpp +++ b/implementation/routing/include/serviceinfo.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -18,7 +18,6 @@ namespace vsomeip_v3 { class endpoint; -class servicegroup; class serviceinfo { public: @@ -28,9 +27,6 @@ public: VSOMEIP_EXPORT serviceinfo(const serviceinfo& _other); VSOMEIP_EXPORT ~serviceinfo(); - VSOMEIP_EXPORT servicegroup * get_group() const; - VSOMEIP_EXPORT void set_group(servicegroup *_group); - VSOMEIP_EXPORT service_t get_service() const; VSOMEIP_EXPORT instance_t get_instance() const; @@ -57,8 +53,6 @@ public: VSOMEIP_EXPORT void set_is_in_mainphase(bool _in_mainphase); private: - servicegroup *group_; - service_t service_; instance_t instance_; diff --git a/implementation/routing/include/types.hpp b/implementation/routing/include/types.hpp index c301b33..d59015c 100644 --- a/implementation/routing/include/types.hpp +++ b/implementation/routing/include/types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -18,18 +18,13 @@ namespace vsomeip_v3 { class serviceinfo; class endpoint_definition; - -typedef std::map > > services_t; +using services_t = std::map>>; class eventgroupinfo; -typedef std::map > > > eventgroups_t; +using eventgroups_t = + std::map>>>; enum class registration_type_e : std::uint8_t { REGISTER = 0x1, @@ -47,8 +42,7 @@ enum class remote_subscription_state_e : std::uint8_t { SUBSCRIPTION_UNKNOWN = 0xFF }; -typedef std::uint16_t remote_subscription_id_t; -typedef std::uint32_t pending_remote_offer_id_t; +using remote_subscription_id_t = std::uint16_t; struct msg_statistic_t { uint32_t counter_; diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp index b63022c..e4eed17 100644 --- a/implementation/routing/src/event.cpp +++ b/implementation/routing/src/event.cpp @@ -1,10 +1,12 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. +#include #include #include +#include #include #include @@ -21,72 +23,104 @@ namespace vsomeip_v3 { -event::event(routing_manager *_routing, bool _is_shadow) : - routing_(_routing), - message_(runtime::get()->create_notification()), - type_(event_type_e::ET_EVENT), - cycle_timer_(_routing->get_io()), - cycle_(std::chrono::milliseconds::zero()), - change_resets_cycle_(false), - is_updating_on_change_(true), - is_set_(false), - is_provided_(false), - is_shadow_(_is_shadow), - is_cache_placeholder_(false), - epsilon_change_func_(std::bind(&event::compare, this, +event::event(routing_manager *_routing, bool _is_shadow) + : routing_(_routing), + current_(runtime::get()->create_notification()), + update_(runtime::get()->create_notification()), + type_(event_type_e::ET_EVENT), + cycle_timer_(_routing->get_io()), + cycle_(std::chrono::milliseconds::zero()), + change_resets_cycle_(false), + is_updating_on_change_(true), + is_set_(false), + is_provided_(false), + is_shadow_(_is_shadow), + is_cache_placeholder_(false), + epsilon_change_func_(std::bind(&event::has_changed, this, std::placeholders::_1, std::placeholders::_2)), - reliability_(reliability_type_e::RT_UNKNOWN) { + reliability_(reliability_type_e::RT_UNKNOWN) { + } -service_t event::get_service() const { - return (message_->get_service()); +service_t +event::get_service() const { + + return (current_->get_service()); } -void event::set_service(service_t _service) { - message_->set_service(_service); +void +event::set_service(service_t _service) { + + current_->set_service(_service); + update_->set_service(_service); } -instance_t event::get_instance() const { - return (message_->get_instance()); +instance_t +event::get_instance() const { + + return (current_->get_instance()); } -void event::set_instance(instance_t _instance) { - message_->set_instance(_instance); +void +event::set_instance(instance_t _instance) { + + current_->set_instance(_instance); + update_->set_instance(_instance); } -major_version_t event::get_version() const { - return message_->get_interface_version(); +major_version_t +event::get_version() const { + + return current_->get_interface_version(); } -void event::set_version(major_version_t _major) { - message_->set_interface_version(_major); +void +event::set_version(major_version_t _major) { + + current_->set_interface_version(_major); + update_->set_interface_version(_major); } -event_t event::get_event() const { - return (message_->get_method()); +event_t +event::get_event() const { + + return (current_->get_method()); } -void event::set_event(event_t _event) { - message_->set_method(_event); +void +event::set_event(event_t _event) { + + current_->set_method(_event); + update_->set_method(_event); } -event_type_e event::get_type() const { +event_type_e +event::get_type() const { + return (type_); } -void event::set_type(const event_type_e _type) { +void +event::set_type(const event_type_e _type) { + type_ = _type; } -bool event::is_field() const { +bool +event::is_field() const { + return (type_ == event_type_e::ET_FIELD); } -bool event::is_provided() const { +bool +event::is_provided() const { + return (is_provided_); } -void event::set_provided(bool _is_provided) { +void +event::set_provided(bool _is_provided) { + is_provided_ = _is_provided; } @@ -94,122 +128,138 @@ bool event::is_set() const { return is_set_; } -const std::shared_ptr event::get_payload() const { +std::shared_ptr +event::get_payload() const { + std::lock_guard its_lock(mutex_); - return (message_->get_payload()); + return (current_->get_payload()); } -bool event::set_payload_dont_notify(const std::shared_ptr &_payload) { +void +event::update_payload() { + std::lock_guard its_lock(mutex_); - if (is_cache_placeholder_) { - reset_payload(_payload); - is_set_ = true; - } else { - if (set_payload_helper(_payload, false)) { - reset_payload(_payload); - } else { - return false; - } - } - return true; + update_payload_unlocked(); +} + +void +event::update_payload_unlocked() { + + current_->set_payload(update_->get_payload()); } -void event::set_payload(const std::shared_ptr &_payload, bool _force) { +void +event::set_payload(const std::shared_ptr &_payload, bool _force) { + std::lock_guard its_lock(mutex_); - if (is_provided_) { - if (set_payload_helper(_payload, _force)) { - reset_payload(_payload); - if (is_updating_on_change_) { - if (change_resets_cycle_) - stop_cycle(); + if (is_provided_ && prepare_update_payload_unlocked(_payload, _force)) { + if (is_updating_on_change_) { + if (change_resets_cycle_) + stop_cycle(); - notify(); + notify(_force); - if (change_resets_cycle_) - start_cycle(); - } + if (change_resets_cycle_) + start_cycle(); + + update_payload_unlocked(); } } else { - VSOMEIP_INFO << "Can't set payload for event " + VSOMEIP_INFO << "Cannot set payload for event [" << std::hex << std::setw(4) << std::setfill('0') - << get_service() << "." << get_instance() << "." << get_event() - << " as it isn't provided"; + << current_->get_service() << "." + << current_->get_instance() << "." + << current_->get_method() + << "]. It isn't provided"; } } -void event::set_payload(const std::shared_ptr &_payload, client_t _client, +void +event::set_payload(const std::shared_ptr &_payload, client_t _client, bool _force) { + std::lock_guard its_lock(mutex_); - if (is_provided_) { - if (set_payload_helper(_payload, _force)) { - reset_payload(_payload); - if (is_updating_on_change_) { - notify_one_unlocked(_client); - } + if (is_provided_ && prepare_update_payload_unlocked(_payload, _force)) { + if (is_updating_on_change_) { + notify_one_unlocked(_client, _force); + update_payload_unlocked(); } } else { - VSOMEIP_INFO << "Can't set payload for event " + VSOMEIP_INFO << "Cannot set payload for event [" << std::hex << std::setw(4) << std::setfill('0') - << get_service() << "." << get_instance() << "." << get_event() - << ". It isn't provided"; + << current_->get_service() << "." + << current_->get_instance() << "." + << current_->get_method() + << "]. It isn't provided"; } } -void event::set_payload(const std::shared_ptr &_payload, +void +event::set_payload(const std::shared_ptr &_payload, const client_t _client, - const std::shared_ptr& _target, - bool _force) { + const std::shared_ptr &_target) { + std::lock_guard its_lock(mutex_); - if (is_provided_) { - if (set_payload_helper(_payload, _force)) { - reset_payload(_payload); - if (is_updating_on_change_) { - notify_one_unlocked(_client, _target); - } + if (is_provided_ && prepare_update_payload_unlocked(_payload, false)) { + if (is_updating_on_change_) { + notify_one_unlocked(_client, _target); + update_payload_unlocked(); } } else { - VSOMEIP_INFO << "Can't set payload for event " + VSOMEIP_INFO << "Cannot set payload for event [" << std::hex << std::setw(4) << std::setfill('0') - << get_service() << "." << get_instance() << "." << get_event() - << ". It isn't provided"; + << current_->get_service() << "." + << current_->get_instance() << "." + << current_->get_method() + << "]. It isn't provided"; } } -bool event::set_payload_notify_pending(const std::shared_ptr &_payload) { +bool +event::set_payload_notify_pending(const std::shared_ptr &_payload) { + std::lock_guard its_lock(mutex_); - if (!is_set_ && is_provided_) { - reset_payload(_payload); + if (is_provided_ && !is_set_) { + + update_->set_payload(_payload); + is_set_ = true; // Send pending initial events. for (const auto &its_target : pending_) { - message_->set_session(routing_->get_session()); + set_session(); routing_->send_to(VSOMEIP_ROUTING_CLIENT, - its_target, message_); + its_target, update_); } pending_.clear(); - return true; + update_payload_unlocked(); + + return (true); } - return false; + return (false); } -void event::unset_payload(bool _force) { +void +event::unset_payload(bool _force) { + std::lock_guard its_lock(mutex_); if (_force) { is_set_ = false; stop_cycle(); - message_->set_payload(std::make_shared()); + current_->set_payload(std::make_shared()); } else { if (is_provided_) { is_set_ = false; stop_cycle(); - message_->set_payload(std::make_shared()); + current_->set_payload(std::make_shared()); } } } -void event::set_update_cycle(std::chrono::milliseconds &_cycle) { +void +event::set_update_cycle(std::chrono::milliseconds &_cycle) { + if (is_provided_) { std::lock_guard its_lock(mutex_); stop_cycle(); @@ -218,24 +268,33 @@ void event::set_update_cycle(std::chrono::milliseconds &_cycle) { } } -void event::set_change_resets_cycle(bool _change_resets_cycle) { +void +event::set_change_resets_cycle(bool _change_resets_cycle) { + change_resets_cycle_ = _change_resets_cycle; } -void event::set_update_on_change(bool _is_active) { +void +event::set_update_on_change(bool _is_active) { + if (is_provided_) { is_updating_on_change_ = _is_active; } } -void event::set_epsilon_change_function(const epsilon_change_func_t &_epsilon_change_func) { +void +event::set_epsilon_change_function( + const epsilon_change_func_t &_epsilon_change_func) { + + std::lock_guard its_lock(mutex_); if (_epsilon_change_func) { - std::lock_guard its_lock(mutex_); epsilon_change_func_ = _epsilon_change_func; } } -const std::set event::get_eventgroups() const { +std::set +event::get_eventgroups() const { + std::set its_eventgroups; { std::lock_guard its_lock(eventgroups_mutex_); @@ -246,7 +305,9 @@ const std::set event::get_eventgroups() const { return its_eventgroups; } -std::set event::get_eventgroups(client_t _client) const { +std::set +event::get_eventgroups(client_t _client) const { + std::set its_eventgroups; std::lock_guard its_lock(eventgroups_mutex_); @@ -257,23 +318,29 @@ std::set event::get_eventgroups(client_t _client) const { return its_eventgroups; } -void event::add_eventgroup(eventgroup_t _eventgroup) { +void +event::add_eventgroup(eventgroup_t _eventgroup) { + std::lock_guard its_lock(eventgroups_mutex_); if (eventgroups_.find(_eventgroup) == eventgroups_.end()) eventgroups_[_eventgroup] = std::set(); } -void event::set_eventgroups(const std::set &_eventgroups) { +void +event::set_eventgroups(const std::set &_eventgroups) { + std::lock_guard its_lock(eventgroups_mutex_); for (auto e : _eventgroups) eventgroups_[e] = std::set(); } -void event::update_cbk(boost::system::error_code const &_error) { +void +event::update_cbk(boost::system::error_code const &_error) { + if (!_error) { std::lock_guard its_lock(mutex_); cycle_timer_.expires_from_now(cycle_); - notify(); + notify(true); auto its_handler = std::bind(&event::update_cbk, shared_from_this(), std::placeholders::_1); @@ -281,10 +348,12 @@ void event::update_cbk(boost::system::error_code const &_error) { } } -void event::notify() { +void +event::notify(bool _force) { + if (is_set_) { - message_->set_session(routing_->get_session()); - routing_->send(VSOMEIP_ROUTING_CLIENT, message_); + set_session(); + routing_->send(VSOMEIP_ROUTING_CLIENT, update_, _force); } else { VSOMEIP_INFO << __func__ << ": Notifying " @@ -294,8 +363,10 @@ void event::notify() { } } -void event::notify_one(client_t _client, +void +event::notify_one(client_t _client, const std::shared_ptr &_target) { + if (_target) { std::lock_guard its_lock(mutex_); notify_one_unlocked(_client, _target); @@ -308,12 +379,14 @@ void event::notify_one(client_t _client, } } -void event::notify_one_unlocked(client_t _client, +void +event::notify_one_unlocked(client_t _client, const std::shared_ptr &_target) { + if (_target) { if (is_set_) { - message_->set_session(routing_->get_session()); - routing_->send_to(_client, _target, message_); + set_session(); + routing_->send_to(_client, _target, update_); } else { VSOMEIP_INFO << __func__ << ": Notifying " @@ -331,15 +404,23 @@ void event::notify_one_unlocked(client_t _client, } } -void event::notify_one(client_t _client) { +void +event::notify_one(client_t _client, bool _force) { + std::lock_guard its_lock(mutex_); - notify_one_unlocked(_client); + notify_one_unlocked(_client, _force); } -void event::notify_one_unlocked(client_t _client) { +void +event::notify_one_unlocked(client_t _client, bool _force) { + if (is_set_) { - message_->set_session(routing_->get_session()); - routing_->send(_client, message_); + set_session(); + { + std::lock_guard its_last_forwarded_guard(last_forwarded_mutex_); + last_forwarded_[_client] = std::chrono::steady_clock::now(); + } + routing_->send(_client, update_, _force); } else { VSOMEIP_INFO << __func__ << ": Notifying " @@ -350,28 +431,46 @@ void event::notify_one_unlocked(client_t _client) { } } -bool event::set_payload_helper(const std::shared_ptr &_payload, bool _force) { - std::shared_ptr its_payload = message_->get_payload(); - bool is_change(type_ != event_type_e::ET_FIELD); - if (!is_change) { - is_change = _force || epsilon_change_func_(its_payload, _payload); - } - return is_change; +bool +event::prepare_update_payload(const std::shared_ptr &_payload, + bool _force) { + + std::lock_guard its_lock(mutex_); + return (prepare_update_payload_unlocked(_payload, _force)); } -void event::reset_payload(const std::shared_ptr &_payload) { - std::shared_ptr its_new_payload +bool +event::prepare_update_payload_unlocked( + const std::shared_ptr &_payload, bool _force) { + + // Copy payload to avoid manipulation from the outside + std::shared_ptr its_payload = runtime::get()->create_payload( - _payload->get_data(), _payload->get_length()); - message_->set_payload(its_new_payload); + _payload->get_data(), _payload->get_length()); + + bool is_change = has_changed(current_->get_payload(), its_payload); + if (!_force + && type_ == event_type_e::ET_FIELD + && cycle_ == std::chrono::milliseconds::zero() + && !is_change) { + + return (false); + } + + if (is_change) + update_->set_payload(its_payload); if (!is_set_) start_cycle(); is_set_ = true; + + return (true); } -void event::add_ref(client_t _client, bool _is_provided) { +void +event::add_ref(client_t _client, bool _is_provided) { + std::lock_guard its_lock(refs_mutex_); auto its_client = refs_.find(_client); if (its_client == refs_.end()) { @@ -386,7 +485,9 @@ void event::add_ref(client_t _client, bool _is_provided) { } } -void event::remove_ref(client_t _client, bool _is_provided) { +void +event::remove_ref(client_t _client, bool _is_provided) { + std::lock_guard its_lock(refs_mutex_); auto its_client = refs_.find(_client); if (its_client != refs_.end()) { @@ -403,24 +504,126 @@ void event::remove_ref(client_t _client, bool _is_provided) { } } -bool event::has_ref() { +bool +event::has_ref() { + std::lock_guard its_lock(refs_mutex_); return refs_.size() != 0; } -bool event::add_subscriber(eventgroup_t _eventgroup, client_t _client, bool _force) { +bool +event::add_subscriber(eventgroup_t _eventgroup, + const std::shared_ptr &_filter, + client_t _client, bool _force) { + std::lock_guard its_lock(eventgroups_mutex_); bool ret = false; if (_force // remote events managed by rm_impl || is_provided_ // events provided by rm_proxies || is_shadow_ // local events managed by rm_impl || is_cache_placeholder_) { + + if (_filter) { + VSOMEIP_WARNING << "Using client [" + << std::hex << std::setw(4) << std::setfill('0') + << _client + << "] specific filter configuration for SOME/IP event " + << get_service() << "." << get_instance() << "." << get_event() << "."; + std::stringstream its_filter_parameters; + its_filter_parameters << "(on_change=" + << std::boolalpha << _filter->on_change_ + << ", interval=" << std::dec << _filter->interval_ + << ", on_change_resets_interval=" + << std::boolalpha << _filter->on_change_resets_interval_ + << ", ignore=[ "; + for (auto i : _filter->ignore_) + its_filter_parameters << "(" << std::dec << i.first << ", " + << std::hex << std::setw(2) << std::setfill('0') + << (int)i.second << ") "; + its_filter_parameters << "])"; + VSOMEIP_INFO << "Filter parameters: " + << its_filter_parameters.str(); + + filters_[_client] = [_filter, _client, this]( + const std::shared_ptr &_old, + const std::shared_ptr &_new) { + + bool is_changed(false), is_elapsed(false); + + // Check whether we should forward because of changed data + if (_filter->on_change_) { + length_t its_min_length, its_max_length; + + if (_old->get_length() < _new->get_length()) { + its_min_length = _old->get_length(); + its_max_length = _new->get_length(); + } else { + its_min_length = _new->get_length(); + its_max_length = _old->get_length(); + } + + // Check whether all additional bytes (if any) are excluded + for (length_t i = its_min_length; i < its_max_length; i++) { + auto j = _filter->ignore_.find(i); + // A change is detected when an additional byte is not + // excluded at all or if its exclusion does not cover all + // bits + if (j == _filter->ignore_.end() || j->second != 0xFF) { + is_changed = true; + break; + } + } + + if (!is_changed) { + const byte_t *its_old = _old->get_data(); + const byte_t *its_new = _new->get_data(); + for (length_t i = 0; i < its_min_length; i++) { + auto j = _filter->ignore_.find(i); + if (j == _filter->ignore_.end()) { + if (its_old[i] != its_new[i]) { + is_changed = true; + break; + } + } else if (j->second != 0xFF) { + if ((its_old[i] & ~(j->second)) != (its_new[i] & ~(j->second))) { + is_changed = true; + break; + } + } + } + } + } + + if (_filter->interval_ > -1) { + // Check whether we should forward because of the elapsed time since + // we did last time + std::chrono::steady_clock::time_point its_current + = std::chrono::steady_clock::now(); + + std::lock_guard its_last_forwarded_guard(last_forwarded_mutex_); + is_elapsed = (last_forwarded_.find(_client) == last_forwarded_.end()); + if (!is_elapsed) { + std::int64_t elapsed = std::chrono::duration_cast( + its_current - last_forwarded_[_client]).count(); + is_elapsed = (elapsed >= _filter->interval_); + } + + if (is_elapsed || (is_changed && _filter->on_change_resets_interval_)) + last_forwarded_[_client] = its_current; + } + + return (is_changed || is_elapsed); + }; + } else { + filters_.erase(_client); + } + ret = eventgroups_[_eventgroup].insert(_client).second; + } else { VSOMEIP_WARNING << __func__ << ": Didnt' insert client " - << std::hex << std::setw(4) << std::setfill('0') - << _client - << " to eventgroup " + << std::hex << std::setw(4) << std::setfill('0') << _client + << " to eventgroup 0x" << std::hex << std::setw(4) << std::setfill('0') << get_service() << "." << get_instance() << "." << _eventgroup; @@ -428,14 +631,21 @@ bool event::add_subscriber(eventgroup_t _eventgroup, client_t _client, bool _for return ret; } -void event::remove_subscriber(eventgroup_t _eventgroup, client_t _client) { +void +event::remove_subscriber(eventgroup_t _eventgroup, client_t _client) { + std::lock_guard its_lock(eventgroups_mutex_); auto find_eventgroup = eventgroups_.find(_eventgroup); if (find_eventgroup != eventgroups_.end()) find_eventgroup->second.erase(_client); + + std::lock_guard its_last_forwarded_guard(last_forwarded_mutex_); + last_forwarded_.erase(_client); } -bool event::has_subscriber(eventgroup_t _eventgroup, client_t _client) { +bool +event::has_subscriber(eventgroup_t _eventgroup, client_t _client) { + std::lock_guard its_lock(eventgroups_mutex_); auto find_eventgroup = eventgroups_.find(_eventgroup); if (find_eventgroup != eventgroups_.end()) { @@ -449,7 +659,9 @@ bool event::has_subscriber(eventgroup_t _eventgroup, client_t _client) { return false; } -std::set event::get_subscribers() { +std::set +event::get_subscribers() { + std::set its_subscribers; std::lock_guard its_lock(eventgroups_mutex_); for (const auto &e : eventgroups_) @@ -457,13 +669,79 @@ std::set event::get_subscribers() { return its_subscribers; } -void event::clear_subscribers() { +std::set +event::get_filtered_subscribers(bool _force) { + + std::set its_subscribers(get_subscribers()); + std::set its_filtered_subscribers; + + std::shared_ptr its_payload, its_payload_update; + { + its_payload = current_->get_payload(); + its_payload_update = update_->get_payload(); + } + + if (filters_.empty()) { + + bool must_forward = (type_ != event_type_e::ET_FIELD + || _force + || epsilon_change_func_(its_payload, its_payload_update)); + + if (must_forward) + return (its_subscribers); + + } else { + byte_t is_allowed(0xff); + + std::lock_guard its_lock(filters_mutex_); + for (const auto s : its_subscribers) { + + auto its_specific = filters_.find(s); + if (its_specific != filters_.end()) { + if (its_specific->second(its_payload, its_payload_update)) + its_filtered_subscribers.insert(s); + } else { + if (is_allowed == 0xff) { + is_allowed = (type_ != event_type_e::ET_FIELD + || _force + || epsilon_change_func_(its_payload, its_payload_update) + ? 0x01 : 0x00); + } + + if (is_allowed == 0x01) + its_filtered_subscribers.insert(s); + } + } + } + + return (its_filtered_subscribers); +} + +std::set +event::update_and_get_filtered_subscribers( + const std::shared_ptr &_payload, bool _is_from_remote) { + + std::lock_guard its_lock(mutex_); + + (void)prepare_update_payload_unlocked(_payload, true); + auto its_subscribers = get_filtered_subscribers(!_is_from_remote); + if (_is_from_remote) + update_payload_unlocked(); + + return (its_subscribers); +} + +void +event::clear_subscribers() { + std::lock_guard its_lock(eventgroups_mutex_); for (auto &e : eventgroups_) e.second.clear(); } -bool event::has_ref(client_t _client, bool _is_provided) { +bool +event::has_ref(client_t _client, bool _is_provided) { + std::lock_guard its_lock(refs_mutex_); auto its_client = refs_.find(_client); if (its_client != refs_.end()) { @@ -477,24 +755,35 @@ bool event::has_ref(client_t _client, bool _is_provided) { return false; } -bool event::is_shadow() const { +bool +event::is_shadow() const { + return is_shadow_; } -void event::set_shadow(bool _shadow) { +void +event::set_shadow(bool _shadow) { + is_shadow_ = _shadow; } -bool event::is_cache_placeholder() const { +bool +event::is_cache_placeholder() const { + return is_cache_placeholder_; } -void event::set_cache_placeholder(bool _is_cache_place_holder) { +void +event::set_cache_placeholder(bool _is_cache_place_holder) { + is_cache_placeholder_ = _is_cache_place_holder; } -void event::start_cycle() { - if (std::chrono::milliseconds::zero() != cycle_) { +void +event::start_cycle() { + + if (!is_shadow_ + && std::chrono::milliseconds::zero() != cycle_) { cycle_timer_.expires_from_now(cycle_); auto its_handler = std::bind(&event::update_cbk, shared_from_this(), @@ -503,15 +792,20 @@ void event::start_cycle() { } } -void event::stop_cycle() { - if (std::chrono::milliseconds::zero() != cycle_) { +void +event::stop_cycle() { + + if (!is_shadow_ + && std::chrono::milliseconds::zero() != cycle_) { boost::system::error_code ec; cycle_timer_.cancel(ec); } } -bool event::compare(const std::shared_ptr &_lhs, +bool +event::has_changed(const std::shared_ptr &_lhs, const std::shared_ptr &_rhs) const { + bool is_change = (_lhs->get_length() != _rhs->get_length()); if (!is_change) { std::size_t its_pos = 0; @@ -522,10 +816,12 @@ bool event::compare(const std::shared_ptr &_lhs, its_pos++; } } - return is_change; + return (is_change); } -std::set event::get_subscribers(eventgroup_t _eventgroup) { +std::set +event::get_subscribers(eventgroup_t _eventgroup) { + std::set its_subscribers; std::lock_guard its_lock(eventgroups_mutex_); auto found_eventgroup = eventgroups_.find(_eventgroup); @@ -535,7 +831,9 @@ std::set event::get_subscribers(eventgroup_t _eventgroup) { return its_subscribers; } -bool event::is_subscribed(client_t _client) { +bool +event::is_subscribed(client_t _client) { + std::lock_guard its_lock(eventgroups_mutex_); for (const auto &egp : eventgroups_) { if (egp.second.find(_client) != egp.second.end()) { @@ -547,18 +845,27 @@ bool event::is_subscribed(client_t _client) { reliability_type_e event::get_reliability() const { + return reliability_; } void event::set_reliability(const reliability_type_e _reliability) { + reliability_ = _reliability; } void event::remove_pending(const std::shared_ptr &_target) { + std::lock_guard its_lock(mutex_); pending_.erase(_target); } +void +event::set_session() { + + update_->set_session(routing_->get_session(false)); +} + } // namespace vsomeip_v3 diff --git a/implementation/routing/src/eventgroupinfo.cpp b/implementation/routing/src/eventgroupinfo.cpp index 50bbdb6..c41f55b 100644 --- a/implementation/routing/src/eventgroupinfo.cpp +++ b/implementation/routing/src/eventgroupinfo.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -119,12 +119,18 @@ void eventgroupinfo::set_multicast(const boost::asio::ip::address &_address, port_ = _port; } -const std::set > eventgroupinfo::get_events() const { +std::set > eventgroupinfo::get_events() const { std::lock_guard its_lock(events_mutex_); return events_; } void eventgroupinfo::add_event(const std::shared_ptr& _event) { + + if (_event == nullptr) { + VSOMEIP_ERROR << __func__ << ": Received ptr is null"; + return; + } + std::lock_guard its_lock(events_mutex_); events_.insert(_event); @@ -158,6 +164,12 @@ void eventgroupinfo::add_event(const std::shared_ptr& _event) { } void eventgroupinfo::remove_event(const std::shared_ptr& _event) { + + if (_event == nullptr) { + VSOMEIP_ERROR << __func__ << ": Received ptr is null"; + return; + } + std::lock_guard its_lock(events_mutex_); events_.erase(_event); } @@ -217,13 +229,19 @@ eventgroupinfo::update_remote_subscription( const bool _is_subscribe) { bool its_result(false); + + if (_subscription == nullptr) { + VSOMEIP_ERROR << __func__ << ": Received ptr is null"; + return (its_result); + } + std::shared_ptr its_subscriber; std::set > its_events; { std::lock_guard its_lock(subscriptions_mutex_); - for (const auto& its_item : subscriptions_) { + for (const auto &its_item : subscriptions_) { if (its_item.second->equals(_subscription)) { // update existing subscription _changed = its_item.second->update( @@ -231,16 +249,17 @@ eventgroupinfo::update_remote_subscription( _id = its_item.second->get_id(); // Copy acknowledgment states from existing subscription - for (const auto& its_client : _subscription->get_clients()) { - const auto its_state = its_item.second->get_client_state(its_client); - if (_is_subscribe && - its_state == remote_subscription_state_e::SUBSCRIPTION_UNKNOWN) { - _subscription->set_client_state(its_client, - remote_subscription_state_e::SUBSCRIPTION_PENDING); + for (const auto its_client : _subscription->get_clients()) { + auto its_state = its_item.second->get_client_state(its_client); + if (_is_subscribe + && its_state == remote_subscription_state_e::SUBSCRIPTION_UNKNOWN) { + // We met the current subscription object during its + // unsubscribe process. Therefore, trigger a resubscription. + its_state = remote_subscription_state_e::SUBSCRIPTION_PENDING; _changed.insert(its_client); - } else { - _subscription->set_client_state(its_client, its_state); } + + _subscription->set_client_state(its_client, its_state); } if (_is_subscribe) { @@ -295,6 +314,11 @@ eventgroupinfo::is_remote_subscription_limit_reached( const std::shared_ptr &_subscription) { bool limit_reached(false); + if (_subscription == nullptr) { + VSOMEIP_ERROR << __func__ << ": Received ptr is null"; + return (limit_reached); + } + if (subscriptions_.size() <= max_remote_subscribers_) { return false; } @@ -321,6 +345,11 @@ eventgroupinfo::is_remote_subscription_limit_reached( remote_subscription_id_t eventgroupinfo::add_remote_subscription( const std::shared_ptr &_subscription) { + + if (_subscription == nullptr) { + VSOMEIP_ERROR << __func__ << ": Received ptr is null"; + return id_; + } std::lock_guard its_lock(subscriptions_mutex_); update_id(); @@ -419,7 +448,6 @@ void eventgroupinfo::send_initial_events( const std::shared_ptr &_reliable, const std::shared_ptr &_unreliable) const { - std::set > its_reliable_events, its_unreliable_events; // Build sets of reliable/unreliable events first to avoid having to @@ -465,11 +493,23 @@ eventgroupinfo::send_initial_events( } // Send events - for (const auto &its_event : its_reliable_events) - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable); + if (!its_reliable_events.empty()) { + if (_reliable != nullptr) { + for (const auto &its_event : its_reliable_events) + its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _reliable); + } else { + VSOMEIP_ERROR << __func__ << ": Received ptr (_reliable) is null"; + } + } - for (const auto &its_event : its_unreliable_events) - its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable); + if (!its_unreliable_events.empty()) { + if (_unreliable != nullptr) { + for (const auto &its_event : its_unreliable_events) + its_event->notify_one(VSOMEIP_ROUTING_CLIENT, _unreliable); + } else { + VSOMEIP_ERROR << __func__ << ": Received ptr (_unreliable) is null"; + } + } } uint8_t eventgroupinfo::get_max_remote_subscribers() const { diff --git a/implementation/routing/src/remote_subscription.cpp b/implementation/routing/src/remote_subscription.cpp index cb04d93..3c95108 100644 --- a/implementation/routing/src/remote_subscription.cpp +++ b/implementation/routing/src/remote_subscription.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2018-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -13,7 +13,6 @@ remote_subscription::remote_subscription() : id_(PENDING_SUBSCRIPTION_ID), is_initial_(true), force_initial_events_(false), - major_(DEFAULT_MAJOR), ttl_(DEFAULT_TTL), reserved_(0), counter_(0), diff --git a/implementation/routing/src/routing_manager_base.cpp b/implementation/routing/src/routing_manager_base.cpp index c787a9e..49dcffb 100644 --- a/implementation/routing/src/routing_manager_base.cpp +++ b/implementation/routing/src/routing_manager_base.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -9,8 +9,8 @@ #include #include "../include/routing_manager_base.hpp" -#include "../../endpoints/include/local_client_endpoint_impl.hpp" -#include "../../endpoints/include/local_server_endpoint_impl.hpp" +#include "../../protocol/include/send_command.hpp" +#include "../../security/include/policy_manager_impl.hpp" #include "../../security/include/security.hpp" #ifdef USE_DLT #include "../../tracing/include/connector_impl.hpp" @@ -23,9 +23,7 @@ namespace vsomeip_v3 { routing_manager_base::routing_manager_base(routing_manager_host *_host) : host_(_host), io_(host_->get_io()), - client_(host_->get_client()), - configuration_(host_->get_configuration()), - routing_state_(routing_state_e::RS_UNKNOWN) + configuration_(host_->get_configuration()) #ifdef USE_DLT , tc_(trace::connector_impl::get()) #endif @@ -41,29 +39,52 @@ routing_manager_base::routing_manager_base(routing_manager_host *_host) : std::make_shared(its_buffer_shrink_threshold)); } - own_uid_ = ANY_UID; - own_gid_ = ANY_GID; -#ifndef _WIN32 - own_uid_ = getuid(); - own_gid_ = getgid(); -#endif - + if (!configuration_->is_local_routing()) { + auto its_routing_address = configuration_->get_routing_host_address(); + auto its_routing_port = configuration_->get_routing_host_port(); + if (!its_routing_address.is_unspecified() && !its_routing_address.is_multicast()) { + add_guest(VSOMEIP_ROUTING_CLIENT, its_routing_address, its_routing_port); + } + } } -boost::asio::io_service & routing_manager_base::get_io() { +boost::asio::io_context &routing_manager_base::get_io() { + return (io_); } client_t routing_manager_base::get_client() const { - return client_; + + return (host_->get_client()); } void routing_manager_base::set_client(const client_t &_client) { - client_ = _client; + + host_->set_client(_client); } -session_t routing_manager_base::get_session() { - return host_->get_session(); +session_t routing_manager_base::get_session(bool _is_request) { + return host_->get_session(_is_request); +} + +const vsomeip_sec_client_t *routing_manager_base::get_sec_client() const { + + return (host_->get_sec_client()); +} + +std::string routing_manager_base::get_client_host() const { + std::lock_guard its_env_lock(env_mutex_); + return env_; +} + +void routing_manager_base::set_client_host(const std::string &_client_host) { + + std::lock_guard its_env_lock(env_mutex_); + env_ = _client_host; +} + +bool routing_manager_base::is_routing_manager() const { + return false; } void routing_manager_base::init(const std::shared_ptr& _endpoint_manager) { @@ -218,25 +239,7 @@ void routing_manager_base::register_event(client_t _client, if (its_event) { if (!its_event->is_cache_placeholder()) { if (_type == its_event->get_type() - || its_event->get_type() == event_type_e::ET_UNKNOWN -#ifdef VSOMEIP_ENABLE_COMPAT - || (its_event->get_type() == event_type_e::ET_EVENT - && _type == event_type_e::ET_SELECTIVE_EVENT) - || (its_event->get_type() == event_type_e::ET_SELECTIVE_EVENT - && _type == event_type_e::ET_EVENT && _is_provided) -#endif - ) { -#ifdef VSOMEIP_ENABLE_COMPAT - if (its_event->get_type() == event_type_e::ET_EVENT - && _type == event_type_e::ET_SELECTIVE_EVENT) { - its_event->set_type(_type); - VSOMEIP_INFO << "Event type changed to selective (" - << std::hex << std::setw(4) << std::setfill('0') << _client << ") [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _notifier << "]"; - } -#endif + || its_event->get_type() == event_type_e::ET_UNKNOWN) { if (_is_provided) { its_event->set_provided(true); its_event->set_reliability(determine_event_reliability()); @@ -319,8 +322,8 @@ void routing_manager_base::register_event(client_t _client, } if (_is_shadow && !_epsilon_change_func) { - std::shared_ptr its_debounce - = configuration_->get_debounce(_service, _instance, _notifier); + std::shared_ptr its_debounce + = configuration_->get_debounce(host_->get_name(), _service, _instance, _notifier); if (its_debounce) { VSOMEIP_WARNING << "Using debounce configuration for " << " SOME/IP event " @@ -344,6 +347,9 @@ void routing_manager_base::register_event(client_t _client, _epsilon_change_func = [its_debounce]( const std::shared_ptr &_old, const std::shared_ptr &_new) { + + static std::chrono::steady_clock::time_point its_last_forwarded + = std::chrono::steady_clock::time_point::max(); bool is_changed(false), is_elapsed(false); // Check whether we should forward because of changed data @@ -362,8 +368,8 @@ void routing_manager_base::register_event(client_t _client, for (length_t i = its_min_length; i < its_max_length; i++) { auto j = its_debounce->ignore_.find(i); // A change is detected when an additional byte is not - // excluded at all or if its exclusion does not cover - // all its bits. + // excluded at all or if its exclusion does not cover all + // bits if (j == its_debounce->ignore_.end() || j->second != 0xFF) { is_changed = true; break; @@ -396,12 +402,12 @@ void routing_manager_base::register_event(client_t _client, std::chrono::steady_clock::time_point its_current = std::chrono::steady_clock::now(); - long elapsed = std::chrono::duration_cast( - its_current - its_debounce->last_forwarded_).count(); - is_elapsed = (its_debounce->last_forwarded_ == (std::chrono::steady_clock::time_point::max)() + std::int64_t elapsed = std::chrono::duration_cast( + its_current - its_last_forwarded).count(); + is_elapsed = (its_last_forwarded == std::chrono::steady_clock::time_point::max() || elapsed >= its_debounce->interval_); if (is_elapsed || (is_changed && its_debounce->on_change_resets_interval_)) - its_debounce->last_forwarded_ = its_current; + its_last_forwarded = its_current; } return (is_changed || is_elapsed); }; @@ -440,14 +446,13 @@ void routing_manager_base::register_event(client_t _client, std::set its_any_event_subscribers = its_any_event->get_subscribers(eventgroup); for (const client_t subscriber : its_any_event_subscribers) { - its_event->add_subscriber(eventgroup, subscriber, true); + its_event->add_subscriber(eventgroup, nullptr, subscriber, true); } } } } } - - if (!its_event->is_cache_placeholder()) { + if(!_is_cache_placeholder) { its_event->add_ref(_client, _is_provided); } @@ -547,8 +552,8 @@ std::vector routing_manager_base::find_events( bool routing_manager_base::is_response_allowed(client_t _sender, service_t _service, instance_t _instance, method_t _method) { - const auto its_security(security::get()); - if (!its_security->is_enabled()) { + if (!configuration_->is_security_enabled() + || !configuration_->is_local_routing()) { return true; } @@ -575,7 +580,7 @@ bool routing_manager_base::is_response_allowed(client_t _sender, service_t _serv // service is now offered by another client // or service is not offered at all std::string security_mode_text = "!"; - if (!its_security->is_audit()) { + if (!configuration_->is_security_audit()) { security_mode_text = ", but will be allowed due to audit mode is active!"; } @@ -586,23 +591,20 @@ bool routing_manager_base::is_response_allowed(client_t _sender, service_t _serv << _service << "/" << _instance << "/" << _method << security_mode_text; - return !its_security->is_audit(); + return !configuration_->is_security_audit(); } -bool routing_manager_base::is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client, +bool routing_manager_base::is_subscribe_to_any_event_allowed( + const vsomeip_sec_client_t *_sec_client, client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup) { - const auto its_security(security::get()); - const uid_t its_uid(std::get<0>(_credentials)); - const gid_t its_gid(std::get<1>(_credentials)); - bool is_allowed(true); auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); if (its_eventgroup) { for (const auto& e : its_eventgroup->get_events()) { - if (!its_security->is_client_allowed(its_uid, its_gid, - _client, _service, _instance, e->get_event())) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member( + _sec_client, _service, _instance, e->get_event())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client << " : routing_manager_base::is_subscribe_to_any_event_allowed: " << "subscribes to service/instance/event " @@ -617,26 +619,64 @@ bool routing_manager_base::is_subscribe_to_any_event_allowed(credentials_t _cred return is_allowed; } -void routing_manager_base::subscribe(client_t _client, uid_t _uid, gid_t _gid, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event) { +void routing_manager_base::add_known_client(client_t _client, const std::string &_client_host) { +#if !defined(VSOMEIP_DISABLE_SECURITY) && (defined(__linux__) || defined(ANDROID)) + std::lock_guard lazy_lock(add_known_client_mutex_); + if (configuration_->is_security_enabled()) { + //Ignore if we have already loaded the policy extension + policy_manager_impl::policy_loaded_e policy_loaded + = policy_manager_impl::get()->is_policy_extension_loaded(_client_host); + + if (policy_loaded == policy_manager_impl::policy_loaded_e::POLICY_PATH_FOUND_AND_NOT_LOADED) + { + if (configuration_->lazy_load_security(_client_host)) { + VSOMEIP_INFO << __func__ << " vSomeIP Security: Loaded security policies for host: " + << _client_host + << " at UID/GID: " << std::dec << getuid() << "/" << getgid(); + } + } else if (policy_loaded == policy_manager_impl::policy_loaded_e::POLICY_PATH_INEXISTENT) { + if (configuration_->lazy_load_security(_client_host)) + { + VSOMEIP_INFO << __func__ << " vSomeIP Security: Loaded security policies for host: " + << _client_host + << " at UID/GID: " << std::dec << getuid() << "/" << getgid(); + } else if (configuration_->lazy_load_security(get_client_host())) { //necessary for lazy loading from inside android container + VSOMEIP_INFO << __func__ << " vSomeIP Security: Loaded security policies for host: " + << get_client_host() + << " at UID/GID: " << std::dec << getuid() << "/" << getgid(); + } + } + } +#endif + std::lock_guard its_lock(known_clients_mutex_); + known_clients_[_client] = _client_host; +} + +void routing_manager_base::subscribe(client_t _client, + const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter) { + + (void)_major; + (void)_sec_client; - (void) _major; - (void)_uid; - (void)_gid; std::set its_already_subscribed_events; bool inserted = insert_subscription(_service, _instance, _eventgroup, - _event, _client, &its_already_subscribed_events); + _event, _filter, _client, &its_already_subscribed_events); if (inserted) { notify_one_current_value(_client, _service, _instance, _eventgroup, _event, its_already_subscribed_events); } } -void routing_manager_base::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, - service_t _service, instance_t _instance, eventgroup_t _eventgroup,event_t _event) { - (void)_uid; - (void)_gid; +void routing_manager_base::unsubscribe(client_t _client, + const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _event) { + + (void)_sec_client; + if (_event != ANY_EVENT) { auto its_event = find_event(_service, _instance, _event); if (its_event) { @@ -653,24 +693,10 @@ void routing_manager_base::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, } } -void -routing_manager_base::unsubscribe_all( - service_t _service, instance_t _instance) { - - std::lock_guard its_guard(events_mutex_); - auto find_service = events_.find(_service); - if (find_service != events_.end()) { - auto find_instance = find_service->second.find(_instance); - if (find_instance != find_service->second.end()) { - for (auto &e : find_instance->second) - e.second->clear_subscribers(); - } - } -} - void routing_manager_base::notify(service_t _service, instance_t _instance, event_t _event, std::shared_ptr _payload, bool _force) { + std::shared_ptr its_event = find_event(_service, _instance, _event); if (its_event) { its_event->set_payload(_payload, _force); @@ -843,7 +869,7 @@ void routing_manager_base::notify_one_current_value( if (_event != ANY_EVENT) { std::shared_ptr its_event = find_event(_service, _instance, _event); if (its_event && its_event->is_field()) - its_event->notify_one(_client); + its_event->notify_one(_client, false); } else { auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); if (its_eventgroup) { @@ -852,7 +878,7 @@ void routing_manager_base::notify_one_current_value( if (e->is_field() && _events_to_exclude.find(e->get_event()) == _events_to_exclude.end()) { - e->notify_one(_client); + e->notify_one(_client, false); } } } @@ -860,7 +886,8 @@ void routing_manager_base::notify_one_current_value( } bool routing_manager_base::send(client_t _client, - std::shared_ptr _message) { + std::shared_ptr _message, bool _force) { + bool is_sent(false); if (utility::is_request(_message->get_message_type())) { _message->set_client(_client); @@ -870,7 +897,8 @@ bool routing_manager_base::send(client_t _client, if (its_serializer->serialize(_message.get())) { is_sent = send(_client, its_serializer->get_data(), its_serializer->get_size(), _message->get_instance(), - _message->is_reliable(), get_client(), std::make_pair(ANY_UID, ANY_GID), 0, false); + _message->is_reliable(), get_client(), get_sec_client(), + 0, false, _force); its_serializer->reset(); put_serializer(its_serializer); } else { @@ -1024,18 +1052,20 @@ void routing_manager_base::remove_local(client_t _client, bool _remove_uid) { void routing_manager_base::remove_local(client_t _client, const std::set>& _subscribed_eventgroups, - bool _remove_uid) { + bool _remove_sec_client) { - std::pair its_uid_gid(ANY_UID, ANY_GID); - security::get()->get_client_to_uid_gid_mapping(_client, its_uid_gid); + vsomeip_sec_client_t its_sec_client; + policy_manager_impl::get()->get_client_to_sec_client_mapping(_client, its_sec_client); - if (_remove_uid) { - security::get()->remove_client_to_uid_gid_mapping(_client); + if (_remove_sec_client) { + policy_manager_impl::get()->remove_client_to_sec_client_mapping(_client); } for (auto its_subscription : _subscribed_eventgroups) { host_->on_subscription(std::get<0>(its_subscription), std::get<1>(its_subscription), - std::get<2>(its_subscription), _client, its_uid_gid.first, its_uid_gid.second, false, [](const bool _subscription_accepted){ (void)_subscription_accepted; }); - routing_manager_base::unsubscribe(_client, its_uid_gid.first, its_uid_gid.second, std::get<0>(its_subscription), + std::get<2>(its_subscription), _client, + &its_sec_client, get_env(_client), + false, [](const bool _subscription_accepted){ (void)_subscription_accepted; }); + routing_manager_base::unsubscribe(_client, &its_sec_client, std::get<0>(its_subscription), std::get<1>(its_subscription), std::get<2>(its_subscription), ANY_EVENT); } ep_mgr_->remove_local(_client); @@ -1047,7 +1077,7 @@ void routing_manager_base::remove_local(client_t _client, for (auto& i : s.second) { if (std::get<2>(i.second) == _client) { its_services.insert({ s.first, i.first }); - host_->on_availability(s.first, i.first, false, + host_->on_availability(s.first, i.first, availability_state_e::AS_UNAVAILABLE, std::get<0>(i.second), std::get<1>(i.second)); } } @@ -1074,9 +1104,7 @@ void routing_manager_base::remove_local(client_t _client, for (auto& sic : its_clients) { local_services_history_[std::get<0>(sic)][std::get<1>(sic)].erase(std::get<2>(sic)); if (local_services_history_[std::get<0>(sic)][std::get<1>(sic)].size() == 0) { - local_services_history_[std::get<0>(sic)].erase(std::get<1>(sic)); - if (local_services_history_[std::get<0>(sic)].size() == 0) - local_services_history_.erase(std::get<0>(sic)); + local_services_history_.erase(std::get<0>(sic)); } } } @@ -1161,7 +1189,7 @@ void routing_manager_base::remove_eventgroup_info(service_t _service, bool routing_manager_base::send_local_notification(client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, - bool _reliable, uint8_t _status_check) { + bool _reliable, uint8_t _status_check, bool _force) { #ifdef USE_DLT bool has_local(false); #endif @@ -1173,7 +1201,7 @@ bool routing_manager_base::send_local_notification(client_t _client, std::shared_ptr its_event = find_event(its_service, _instance, its_method); if (its_event && !its_event->is_shadow()) { - for (auto its_client : its_event->get_subscribers()) { + for (auto its_client : its_event->get_filtered_subscribers(_force)) { // local if (its_client == VSOMEIP_ROUTING_CLIENT) { @@ -1189,60 +1217,57 @@ bool routing_manager_base::send_local_notification(client_t _client, std::shared_ptr its_local_target = ep_mgr_->find_local(its_client); if (its_local_target) { send_local(its_local_target, _client, _data, _size, - _instance, _reliable, VSOMEIP_SEND, _status_check); + _instance, _reliable, protocol::id_e::SEND_ID, _status_check); } } } #ifdef USE_DLT // Trace the message if a local client but will _not_ be forwarded to the routing manager if (has_local && !has_remote) { - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(nullptr, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); } #endif return has_remote; } bool routing_manager_base::send_local( - std::shared_ptr& _target, client_t _client, + std::shared_ptr &_target, client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, - bool _reliable, uint8_t _command, uint8_t _status_check) const { - const std::size_t its_complete_size = VSOMEIP_SEND_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE + _size; - const client_t sender = get_client(); - - std::vector its_command_header(VSOMEIP_SEND_COMMAND_SIZE); - its_command_header[VSOMEIP_COMMAND_TYPE_POS] = _command; - std::memcpy(&its_command_header[VSOMEIP_COMMAND_CLIENT_POS], - &sender, sizeof(client_t)); - std::memcpy(&its_command_header[VSOMEIP_COMMAND_SIZE_POS_MIN], - &its_complete_size, sizeof(_size)); - std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN], - &_instance, sizeof(instance_t)); - std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_RELIABLE_POS], - &_reliable, sizeof(bool)); - std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS], - &_status_check, sizeof(uint8_t)); - // Add target client, only relevant for selective notifications - std::memcpy(&its_command_header[VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN], - &_client, sizeof(client_t)); - - return _target->send(its_command_header, _data, _size); + bool _reliable, protocol::id_e _command, uint8_t _status_check) const { + + bool has_sent(false); + + protocol::send_command its_command(_command); + its_command.set_client(get_client()); + its_command.set_instance(_instance); + its_command.set_reliable(_reliable); + its_command.set_status(_status_check); + its_command.set_target(_client); + its_command.set_message(std::vector(_data, _data + _size)); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + has_sent = _target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + + return (has_sent); } bool routing_manager_base::insert_subscription( service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, client_t _client, std::set *_already_subscribed_events) { + event_t _event, const std::shared_ptr &_filter, + client_t _client, std::set *_already_subscribed_events) { + bool is_inserted(false); if (_event != ANY_EVENT) { // subscribe to specific event std::shared_ptr its_event = find_event(_service, _instance, _event); if (its_event) { - is_inserted = its_event->add_subscriber(_eventgroup, _client, + is_inserted = its_event->add_subscriber(_eventgroup, _filter, _client, host_->is_routing()); } else { VSOMEIP_WARNING << "routing_manager_base::insert_subscription(" @@ -1255,7 +1280,7 @@ bool routing_manager_base::insert_subscription( << "unoffered) event. Creating placeholder event holding " << "subscription until event is requested/offered."; is_inserted = create_placeholder_event_and_subscribe(_service, - _instance, _eventgroup, _event, _client); + _instance, _eventgroup, _event, _filter, _client); } } else { // subscribe to all events of the eventgroup std::shared_ptr its_eventgroup @@ -1273,7 +1298,7 @@ bool routing_manager_base::insert_subscription( // eventgroups _already_subscribed_events->insert(e->get_event()); } - is_inserted = e->add_subscriber(_eventgroup, _client, + is_inserted = e->add_subscriber(_eventgroup, _filter, _client, host_->is_routing()) || is_inserted; } } @@ -1291,7 +1316,7 @@ bool routing_manager_base::insert_subscription( << "unoffered) eventgroup. Creating placeholder event holding " << "subscription until event is requested/offered."; is_inserted = create_placeholder_event_and_subscribe(_service, - _instance, _eventgroup, _event, _client); + _instance, _eventgroup, _event, _filter, _client); } } return is_inserted; @@ -1305,7 +1330,8 @@ std::shared_ptr routing_manager_base::get_serializer() { << std::hex << std::setw(4) << std::setfill('0') << get_client() << " has no available serializer. Waiting..."; - serializer_condition_.wait(its_lock); + + serializer_condition_.wait(its_lock, [this] { return !serializers_.empty(); }); VSOMEIP_INFO << __func__ << ": Client " << std::hex << std::setw(4) << std::setfill('0') << get_client() @@ -1332,7 +1358,8 @@ std::shared_ptr routing_manager_base::get_deserializer() { while (deserializers_.empty()) { VSOMEIP_INFO << std::hex << "client " << get_client() << "routing_manager_base::get_deserializer ~> all in use!"; - deserializer_condition_.wait(its_lock); + + deserializer_condition_.wait(its_lock, [this] { return !deserializers_.empty(); }); VSOMEIP_INFO << std::hex << "client " << get_client() << "routing_manager_base::get_deserializer ~> wait finished!"; } @@ -1356,8 +1383,8 @@ void routing_manager_base::send_pending_subscriptions(service_t _service, for (auto &ps : pending_subscriptions_) { if (ps.service_ == _service && ps.instance_ == _instance && ps.major_ == _major) { - send_subscribe(client_, ps.service_, ps.instance_, - ps.eventgroup_, ps.major_, ps.event_); + send_subscribe(get_client(), ps.service_, ps.instance_, + ps.eventgroup_, ps.major_, ps.event_, ps.filter_); } } } @@ -1421,6 +1448,47 @@ routing_manager_base::get_subscriptions(const client_t _client) { return result; } +bool +routing_manager_base::get_guest(client_t _client, + boost::asio::ip::address &_address, port_t &_port) const { + + std::lock_guard its_lock(guests_mutex_); + auto find_guest = guests_.find(_client); + if (find_guest == guests_.end()) + return (false); + + _address = find_guest->second.first; + _port = find_guest->second.second; + + return (true); +} + +void +routing_manager_base::add_guest(client_t _client, + const boost::asio::ip::address &_address, port_t _port) { + + std::lock_guard its_lock(guests_mutex_); + guests_[_client] = std::make_pair(_address, _port); +} + +void +routing_manager_base::remove_guest(client_t _client) { + + std::lock_guard its_lock(guests_mutex_); + guests_.erase(_client); +} + +void +routing_manager_base::remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port) { + + (void)_local_port; + (void)_remote_address; + (void)_remote_port; + // dummy method to implement routing_host interface +} + routing_state_e routing_manager_base::get_routing_state() { return routing_state_; diff --git a/implementation/routing/src/routing_manager_client.cpp b/implementation/routing/src/routing_manager_client.cpp new file mode 100644 index 0000000..378ab5d --- /dev/null +++ b/implementation/routing/src/routing_manager_client.cpp @@ -0,0 +1,2890 @@ +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#if defined(__linux__) || defined(ANDROID) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "../include/event.hpp" +#include "../include/routing_manager_host.hpp" +#include "../include/routing_manager_client.hpp" +#include "../../configuration/include/configuration.hpp" +#include "../../endpoints/include/netlink_connector.hpp" +#include "../../message/include/deserializer.hpp" +#include "../../message/include/message_impl.hpp" +#include "../../message/include/serializer.hpp" +#include "../../protocol/include/assign_client_command.hpp" +#include "../../protocol/include/assign_client_ack_command.hpp" +#include "../../protocol/include/deregister_application_command.hpp" +#include "../../protocol/include/distribute_security_policies_command.hpp" +#include "../../protocol/include/dummy_command.hpp" +#include "../../protocol/include/expire_command.hpp" +#include "../../protocol/include/offer_service_command.hpp" +#include "../../protocol/include/offered_services_request_command.hpp" +#include "../../protocol/include/offered_services_response_command.hpp" +#include "../../protocol/include/ping_command.hpp" +#include "../../protocol/include/pong_command.hpp" +#include "../../protocol/include/register_application_command.hpp" +#include "../../protocol/include/register_events_command.hpp" +#include "../../protocol/include/registered_ack_command.hpp" +#include "../../protocol/include/release_service_command.hpp" +#include "../../protocol/include/remove_security_policy_command.hpp" +#include "../../protocol/include/remove_security_policy_response_command.hpp" +#include "../../protocol/include/request_service_command.hpp" +#include "../../protocol/include/resend_provided_events_command.hpp" +#include "../../protocol/include/routing_info_command.hpp" +#include "../../protocol/include/send_command.hpp" +#include "../../protocol/include/stop_offer_service_command.hpp" +#include "../../protocol/include/subscribe_ack_command.hpp" +#include "../../protocol/include/subscribe_command.hpp" +#include "../../protocol/include/subscribe_nack_command.hpp" +#include "../../protocol/include/unregister_event_command.hpp" +#include "../../protocol/include/unsubscribe_ack_command.hpp" +#include "../../protocol/include/unsubscribe_command.hpp" +#include "../../protocol/include/update_security_credentials_command.hpp" +#include "../../protocol/include/update_security_policy_command.hpp" +#include "../../protocol/include/update_security_policy_response_command.hpp" +#include "../../service_discovery/include/runtime.hpp" +#include "../../security/include/policy.hpp" +#include "../../security/include/policy_manager_impl.hpp" +#include "../../security/include/security.hpp" +#include "../../utility/include/byteorder.hpp" +#include "../../utility/include/utility.hpp" +#ifdef USE_DLT +#include "../../tracing/include/connector_impl.hpp" +#endif + +namespace vsomeip_v3 { + +routing_manager_client::routing_manager_client(routing_manager_host *_host, + bool _client_side_logging, + const std::set > & _client_side_logging_filter) : + routing_manager_base(_host), + is_connected_(false), + is_started_(false), + state_(inner_state_type_e::ST_DEREGISTERED), + sender_(nullptr), + receiver_(nullptr), + register_application_timer_(io_), + request_debounce_timer_ (io_), + request_debounce_timer_running_(false), + client_side_logging_(_client_side_logging), + client_side_logging_filter_(_client_side_logging_filter) +#if defined(__linux__) || defined(ANDROID) + , is_local_link_available_(false) +#endif // defined(__linux__) || defined(ANDROID) +{ + + char its_hostname[1024]; + if (gethostname(its_hostname, sizeof(its_hostname)) == 0) { + set_client_host(its_hostname); + } +} + +routing_manager_client::~routing_manager_client() { +} + +void routing_manager_client::init() { + routing_manager_base::init(std::make_shared(this, io_, configuration_)); + { + std::lock_guard its_lock(sender_mutex_); + if (configuration_->is_local_routing()) { + sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT); + } else { +#if defined(__linux__) || defined(ANDROID) + auto its_guest_address = configuration_->get_routing_guest_address(); + auto its_host_address = configuration_->get_routing_host_address(); + local_link_connector_ = std::make_shared( + io_, its_guest_address, boost::asio::ip::address(), + (its_guest_address != its_host_address)); + // if the guest is in the same node as the routing manager + // it should not require LINK to be UP to communicate + + if (local_link_connector_) { + local_link_connector_->register_net_if_changes_handler( + std::bind(&routing_manager_client::on_net_state_change, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + } +#else + receiver_ = ep_mgr_->create_local_server(shared_from_this()); + sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT); +#endif + } + } +} + +void routing_manager_client::start() { + +#if defined(__linux__) || defined(ANDROID) + if (configuration_->is_local_routing()) { +#else + { +#endif // __linux__ || ANDROID + is_started_ = true; + { + std::lock_guard its_lock(sender_mutex_); + if (!sender_) { + // application has been stopped and started again + sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT); + } + if (sender_) { + sender_->start(); + } + } +#if defined(__linux__) || defined(ANDROID) + } else { + if (local_link_connector_) + local_link_connector_->start(); +#endif // __linux__ || ANDROID + } +} + +void routing_manager_client::stop() { + std::unique_lock its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERING) { + register_application_timer_.cancel(); + } + + const std::chrono::milliseconds its_timeout(configuration_->get_shutdown_timeout()); + while (state_ == inner_state_type_e::ST_REGISTERING) { + std::cv_status status = state_condition_.wait_for(its_lock, its_timeout); + if (status == std::cv_status::timeout) { + VSOMEIP_WARNING << std::hex << get_client() << " registering timeout on stop"; + break; + } + } + + if (state_ == inner_state_type_e::ST_REGISTERED) { + deregister_application(); + // Waiting de-register acknowledge to synchronize shutdown + while (state_ == inner_state_type_e::ST_REGISTERED) { + std::cv_status status = state_condition_.wait_for(its_lock, its_timeout); + if (status == std::cv_status::timeout) { + VSOMEIP_WARNING << std::hex << get_client() << " couldn't deregister application - timeout"; + break; + } + } + } + is_started_ = false; + its_lock.unlock(); + +#if defined(__linux__) || defined(ANDROID) + if (local_link_connector_) + local_link_connector_->stop(); +#endif + + { + std::lock_guard its_lock(request_timer_mutex_); + request_debounce_timer_.cancel(); + } + + if (receiver_) { + receiver_->stop(); + } + receiver_ = nullptr; + + { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->stop(); + } + // delete the sender + sender_ = nullptr; + } + + for (const auto client : ep_mgr_->get_connected_clients()) { + if (client != VSOMEIP_ROUTING_CLIENT) { + remove_local(client, true); + } + } + + if (configuration_->is_local_routing()) { + std::stringstream its_client; + its_client << utility::get_base_path(configuration_->get_network()) + << std::hex << get_client(); + #ifdef _WIN32 + ::_unlink(its_client.str().c_str()); + #else + + if (-1 == ::unlink(its_client.str().c_str())) { + VSOMEIP_ERROR<< "routing_manager_proxy::stop unlink failed (" + << its_client.str() << "): "<< std::strerror(errno); + } + #endif + } +} + +#if defined(__linux__) || defined(ANDROID) +void +routing_manager_client::on_net_state_change( + bool _is_interface, const std::string &_name, bool _is_available) { + + VSOMEIP_INFO << __func__ + << ": " << std::boolalpha << _is_interface << " " + << _name << " " + << std::boolalpha << _is_available; + + if (_is_interface) { + if (_is_available) { + if (!is_local_link_available_) { + + is_local_link_available_ = true; + + if (!receiver_) + receiver_ = ep_mgr_->create_local_server(shared_from_this()); + receiver_->start(); + is_started_ = true; + + if (!sender_) + sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT); + sender_->start(); + } + } else { + if (is_local_link_available_) { + is_started_ = false; + + state_ = inner_state_type_e::ST_DEREGISTERED; + on_disconnect(sender_); + + sender_->stop(); + + receiver_->stop(); + + { + std::lock_guard its_lock(local_services_mutex_); + local_services_.clear(); + } + + is_local_link_available_ = false; + } + } + } +} +#endif // __linux__ || ANDROID + +std::shared_ptr routing_manager_client::get_configuration() const { + return host_->get_configuration(); +} + +std::string routing_manager_client::get_env(client_t _client) const { + + std::lock_guard its_known_clients_lock(known_clients_mutex_); + return get_env_unlocked(_client); +} + +std::string routing_manager_client::get_env_unlocked(client_t _client) const { + + auto find_client = known_clients_.find(_client); + if (find_client != known_clients_.end()) { + return (find_client->second); + } + return ""; +} + +bool routing_manager_client::offer_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + + if (!routing_manager_base::offer_service(_client, _service, _instance, _major, _minor)) { + VSOMEIP_WARNING << "routing_manager_client::offer_service," + << "routing_manager_base::offer_service returned false"; + } + { + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERED) { + send_offer_service(_client, _service, _instance, _major, _minor); + } + protocol::service offer(_service, _instance, _major, _minor ); + pending_offers_.insert(offer); + } + return true; +} + +void routing_manager_client::send_offer_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + + (void)_client; + + protocol::offer_service_command its_offer; + its_offer.set_client(get_client()); + its_offer.set_service(_service); + its_offer.set_instance(_instance); + its_offer.set_major(_major); + its_offer.set_minor(_minor); + + std::vector its_buffer; + protocol::error_e its_error; + its_offer.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else { + VSOMEIP_ERROR << __func__ << ": offer_service serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } + +} + +void routing_manager_client::stop_offer_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + + (void)_client; + + { + // Hold the mutex to ensure no placeholder event is created inbetween. + std::lock_guard its_lock(stop_mutex_); + + routing_manager_base::stop_offer_service(_client, _service, _instance, _major, _minor); + clear_remote_subscriber_count(_service, _instance); + + // Note: The last argument does not matter here as a proxy + // does not manage endpoints to the external network. + clear_service_info(_service, _instance, false); + } + + { + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERED) { + + protocol::stop_offer_service_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_major(_major); + its_command.set_minor(_minor); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else { + VSOMEIP_ERROR << __func__ << ": stop offer serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } + } + auto it = pending_offers_.begin(); + while (it != pending_offers_.end()) { + if (it->service_ == _service + && it->instance_ == _instance) { + break; + } + it++; + } + if (it != pending_offers_.end()) pending_offers_.erase(it); + } +} + +void routing_manager_client::request_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + routing_manager_base::request_service(_client, + _service, _instance, _major, _minor); + { + std::lock_guard its_lock(state_mutex_); + size_t request_debouncing_time = configuration_->get_request_debouncing(host_->get_name()); + protocol::service request = { _service, _instance, _major, _minor }; + if (!request_debouncing_time) { + if (state_ == inner_state_type_e::ST_REGISTERED) { + std::set requests; + requests.insert(request); + send_request_services(requests); + } + requests_.insert(request); + } else { + requests_to_debounce_.insert(request); + std::lock_guard its_lock(request_timer_mutex_); + if (!request_debounce_timer_running_) { + request_debounce_timer_running_ = true; + request_debounce_timer_.expires_from_now(std::chrono::milliseconds(request_debouncing_time)); + request_debounce_timer_.async_wait( + std::bind( + &routing_manager_client::request_debounce_timeout_cbk, + std::dynamic_pointer_cast(shared_from_this()), + std::placeholders::_1)); + } + } + } +} + +void routing_manager_client::release_service(client_t _client, + service_t _service, instance_t _instance) { + routing_manager_base::release_service(_client, _service, _instance); + { + std::lock_guard its_lock(state_mutex_); + remove_pending_subscription(_service, _instance, 0xFFFF, ANY_EVENT); + + bool pending(false); + auto it = requests_to_debounce_.begin(); + while (it != requests_to_debounce_.end()) { + if (it->service_ == _service + && it->instance_ == _instance) { + pending = true; + } + it++; + } + if (it != requests_to_debounce_.end()) requests_to_debounce_.erase(it); + + if (!pending && state_ == inner_state_type_e::ST_REGISTERED) { + send_release_service(_client, _service, _instance); + } + + { + auto it = requests_.begin(); + while (it != requests_.end()) { + if (it->service_ == _service + && it->instance_ == _instance) { + break; + } + it++; + } + if (it != requests_.end()) requests_.erase(it); + } + } +} + + +void routing_manager_client::register_event(client_t _client, + service_t _service, instance_t _instance, + event_t _notifier, + const std::set &_eventgroups, const event_type_e _type, + reliability_type_e _reliability, + std::chrono::milliseconds _cycle, bool _change_resets_cycle, + bool _update_on_change, epsilon_change_func_t _epsilon_change_func, + bool _is_provided, bool _is_shadow, bool _is_cache_placeholder) { + + (void)_is_shadow; + (void)_is_cache_placeholder; + + bool is_cyclic(_cycle != std::chrono::milliseconds::zero()); + + const event_data_t registration = { + _service, + _instance, + _notifier, + _type, + _reliability, + _is_provided, + is_cyclic, + _eventgroups + }; + bool is_first(false); + { + std::lock_guard its_lock(state_mutex_); + is_first = pending_event_registrations_.find(registration) + == pending_event_registrations_.end(); +#ifndef VSOMEIP_ENABLE_COMPAT + if (is_first) { + pending_event_registrations_.insert(registration); + } +#else + bool insert = true; + if (is_first) { + for (auto iter = pending_event_registrations_.begin(); + iter != pending_event_registrations_.end();) { + if (iter->service_ == _service + && iter->instance_ == _instance + && iter->notifier_ == _notifier + && iter->is_provided_ == _is_provided + && iter->type_ == event_type_e::ET_EVENT + && _type == event_type_e::ET_SELECTIVE_EVENT) { + iter = pending_event_registrations_.erase(iter); + iter = pending_event_registrations_.insert(registration).first; + is_first = true; + insert = false; + break; + } else { + iter++; + } + } + if (insert) { + pending_event_registrations_.insert(registration); + } + } +#endif + } + if (is_first || _is_provided) { + routing_manager_base::register_event(_client, + _service, _instance, + _notifier, + _eventgroups, _type, _reliability, + _cycle, _change_resets_cycle, _update_on_change, + _epsilon_change_func, + _is_provided); + } + { + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERED && is_first) { + send_register_event(get_client(), _service, _instance, + _notifier, _eventgroups, _type, _reliability, + _is_provided, is_cyclic); + } + } +} + +void routing_manager_client::unregister_event(client_t _client, + service_t _service, instance_t _instance, event_t _notifier, + bool _is_provided) { + + routing_manager_base::unregister_event(_client, _service, _instance, + _notifier, _is_provided); + + { + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERED) { + + protocol::unregister_event_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_event(_notifier); + its_command.set_provided(_is_provided); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } + + for (auto iter = pending_event_registrations_.begin(); + iter != pending_event_registrations_.end(); ) { + if (iter->service_ == _service + && iter->instance_ == _instance + && iter->notifier_ == _notifier + && iter->is_provided_ == _is_provided) { + pending_event_registrations_.erase(iter); + break; + } else { + iter++; + } + } + } +} + +bool routing_manager_client::is_field(service_t _service, instance_t _instance, + event_t _event) const { + auto event = find_event(_service, _instance, _event); + if (event && event->is_field()) { + return true; + } + return false; +} + +void routing_manager_client::subscribe( + client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter) { + + (void)_client; + + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERED && is_available(_service, _instance, _major)) { + send_subscribe(get_client(), _service, _instance, _eventgroup, _major, _event, _filter ); + } + subscription_data_t subscription = { + _service, _instance, + _eventgroup, _major, + _event, _filter, + *_sec_client + }; + pending_subscriptions_.insert(subscription); +} + +void routing_manager_client::send_subscribe(client_t _client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter) { + + if (_event == ANY_EVENT) { + if (!is_subscribe_to_any_event_allowed(get_sec_client(), _client, _service, _instance, _eventgroup)) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client + << " : routing_manager_proxy::subscribe: " + << " isn't allowed to subscribe to service/instance/event " + << _service << "/" << _instance << "/ANY_EVENT" + << " which violates the security policy ~> Skip subscribe!"; + return; + } + } else { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member( + get_sec_client(), _service, _instance, _event)) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client + << " : routing_manager_proxy::subscribe: " + << " isn't allowed to subscribe to service/instance/event " + << _service << "/" << _instance + << "/" << _event; + return; + } + } + + protocol::subscribe_command its_command; + its_command.set_client(_client); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_major(_major); + its_command.set_event(_event); + its_command.set_pending_id(PENDING_SUBSCRIPTION_ID); + its_command.set_filter(_filter); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + client_t its_target_client = find_local_client(_service, _instance); + if (its_target_client != VSOMEIP_ROUTING_CLIENT) { + auto its_target = ep_mgr_->find_or_create_local(its_target_client); + its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } else { + VSOMEIP_ERROR << __func__ << ": subscribe command serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } +} + +void routing_manager_client::send_subscribe_nack(client_t _subscriber, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _event, remote_subscription_id_t _id) { + + protocol::subscribe_nack_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_subscriber(_subscriber); + its_command.set_event(_event); + its_command.set_pending_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + if (_subscriber != VSOMEIP_ROUTING_CLIENT + && _id == PENDING_SUBSCRIPTION_ID) { + auto its_target = ep_mgr_->find_local(_subscriber); + if (its_target) { + its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + return; + } + } + { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } else { + VSOMEIP_ERROR << __func__ << ": subscribe nack serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } +} + +void routing_manager_client::send_subscribe_ack(client_t _subscriber, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _event, remote_subscription_id_t _id) { + + protocol::subscribe_ack_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_subscriber(_subscriber); + its_command.set_event(_event); + its_command.set_pending_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + if (_subscriber != VSOMEIP_ROUTING_CLIENT + && _id == PENDING_SUBSCRIPTION_ID) { + auto its_target = ep_mgr_->find_local(_subscriber); + if (its_target) { + its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + return; + } + } + { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } else { + VSOMEIP_ERROR << __func__ << ": subscribe ack serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } +} + +void routing_manager_client::unsubscribe(client_t _client, + const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { + + (void)_client; + (void)_sec_client; + + { + std::lock_guard its_lock(state_mutex_); + remove_pending_subscription(_service, _instance, _eventgroup, _event); + + if (state_ == inner_state_type_e::ST_REGISTERED) { + + protocol::unsubscribe_command its_command; + its_command.set_client(_client); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_major(ANY_MAJOR); + its_command.set_event(_event); + its_command.set_pending_id(PENDING_SUBSCRIPTION_ID); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + + auto its_target = ep_mgr_->find_local(_service, _instance); + if (its_target) { + its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } else { + + VSOMEIP_ERROR << __func__ + << ": unsubscribe serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } + } + } +} + +bool routing_manager_client::send(client_t _client, const byte_t *_data, + length_t _size, instance_t _instance, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + uint8_t _status_check, bool _sent_from_remote, bool _force) { + + (void)_client; + (void)_bound_client; + (void)_sec_client; + (void)_sent_from_remote; + bool is_sent(false); + bool has_remote_subscribers(false); + { + std::lock_guard its_lock(state_mutex_); + if (state_ != inner_state_type_e::ST_REGISTERED) { + return false; + } + } + if (client_side_logging_) { + if (_size > VSOMEIP_MESSAGE_TYPE_POS) { + service_t its_service = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_SERVICE_POS_MIN], + _data[VSOMEIP_SERVICE_POS_MAX]); + if (client_side_logging_filter_.empty() + || (1 == client_side_logging_filter_.count(std::make_tuple(its_service, ANY_INSTANCE))) + || (1 == client_side_logging_filter_.count(std::make_tuple(its_service, _instance)))) { + method_t its_method = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_METHOD_POS_MIN], + _data[VSOMEIP_METHOD_POS_MAX]); + session_t its_session = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_SESSION_POS_MIN], + _data[VSOMEIP_SESSION_POS_MAX]); + client_t its_client = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_CLIENT_POS_MIN], + _data[VSOMEIP_CLIENT_POS_MAX]); + VSOMEIP_INFO << "routing_manager_client::send: (" + << std::hex << std::setw(4) << std::setfill('0') << get_client() <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_method << ":" + << std::hex << std::setw(4) << std::setfill('0') << its_session << ":" + << std::hex << std::setw(4) << std::setfill('0') << its_client << "] " + << "type=" << std::hex << static_cast(_data[VSOMEIP_MESSAGE_TYPE_POS]) + << " thread=" << std::hex << std::this_thread::get_id(); + } + } else { + VSOMEIP_ERROR << "routing_manager_client::send: (" + << std::hex << std::setw(4) << std::setfill('0') << get_client() + <<"): message too short to log: " << std::dec << _size; + } + } + if (_size > VSOMEIP_MESSAGE_TYPE_POS) { + std::shared_ptr its_target; + if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { + // Request + service_t its_service = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_SERVICE_POS_MIN], + _data[VSOMEIP_SERVICE_POS_MAX]); + client_t its_client = find_local_client(its_service, _instance); + if (its_client != VSOMEIP_ROUTING_CLIENT) { + if (is_client_known(its_client)) { + its_target = ep_mgr_->find_or_create_local(its_client); + } + } + } else if (!utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) { + // Response + client_t its_client = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_CLIENT_POS_MIN], + _data[VSOMEIP_CLIENT_POS_MAX]); + if (its_client != VSOMEIP_ROUTING_CLIENT) { + if (is_client_known(its_client)) { + its_target = ep_mgr_->find_or_create_local(its_client); + } + } + } else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) && + _client == VSOMEIP_ROUTING_CLIENT) { + // notify + has_remote_subscribers = send_local_notification(get_client(), _data, _size, + _instance, _reliable, _status_check, _force); + } else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) && + _client != VSOMEIP_ROUTING_CLIENT) { + // notify_one + its_target = ep_mgr_->find_local(_client); + if (its_target) { +#ifdef USE_DLT + trace::header its_header; + if (its_header.prepare(nullptr, true, _instance)) + tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, + _data, _size); +#endif + return send_local(its_target, get_client(), _data, _size, + _instance, _reliable, protocol::id_e::SEND_ID, _status_check); + } + } + // If no direct endpoint could be found + // or for notifications ~> route to routing_manager_stub +#ifdef USE_DLT + bool message_to_stub(false); +#endif + if (!its_target) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + its_target = sender_; +#ifdef USE_DLT + message_to_stub = true; +#endif + } else { + return false; + } + } + + bool send(true); + protocol::id_e its_command(protocol::id_e::SEND_ID); + + if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) { + if (_client != VSOMEIP_ROUTING_CLIENT) { + its_command = protocol::id_e::NOTIFY_ONE_ID; + } else { + its_command = protocol::id_e::NOTIFY_ID; + // Do we need to deliver a notification to the routing manager? + // Only for services which already have remote clients subscribed to + send = has_remote_subscribers; + } + } +#ifdef USE_DLT + else if (!message_to_stub) { + trace::header its_header; + if (its_header.prepare(nullptr, true, _instance)) + tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, + _data, _size); + } +#endif + if (send) { + is_sent = send_local(its_target, + (its_command == protocol::id_e::NOTIFY_ONE_ID ? _client : get_client()), + _data, _size, _instance, _reliable, its_command, _status_check); + } + } + return (is_sent); +} + +bool routing_manager_client::send_to(const client_t _client, + const std::shared_ptr &_target, + std::shared_ptr _message) { + + (void)_client; + (void)_target; + (void)_message; + + return (false); +} + +bool routing_manager_client::send_to( + const std::shared_ptr &_target, + const byte_t *_data, uint32_t _size, instance_t _instance) { + + (void)_target; + (void)_data; + (void)_size; + (void)_instance; + + return (false); +} + +void routing_manager_client::on_connect(const std::shared_ptr& _endpoint) { + + _endpoint->set_connected(true); + _endpoint->set_established(true); + { + std::lock_guard its_lock(sender_mutex_); + if (_endpoint != sender_) { + return; + } + } + is_connected_ = true; + assign_client(); +} + +void routing_manager_client::on_disconnect(const std::shared_ptr& _endpoint) { + { + std::lock_guard its_lock(sender_mutex_); + is_connected_ = !(_endpoint == sender_); + } + if (!is_connected_) { + VSOMEIP_INFO << "routing_manager_client::on_disconnect: Client 0x" << std::hex + << get_client() << " calling host_->on_state " + << "with DEREGISTERED"; + host_->on_state(state_type_e::ST_DEREGISTERED); + } +} + +void routing_manager_client::on_message( + const byte_t *_data, length_t _size, + endpoint *_receiver, bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + const boost::asio::ip::address &_remote_address, + std::uint16_t _remote_port) { + + (void)_receiver; + (void)_is_multicast; + (void)_remote_address; + (void)_remote_port; + +#if 0 + std::stringstream msg; + msg << "rmp::on_message<" << std::hex << get_client() << ">: "; + for (length_t i = 0; i < _size; ++i) + msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + protocol::id_e its_id; + client_t its_client; + service_t its_service; + instance_t its_instance; + eventgroup_t its_eventgroup; + event_t its_event; + major_version_t its_major; + client_t routing_host_id = configuration_->get_id( + configuration_->get_routing_host_name()); + client_t its_subscriber; + remote_subscription_id_t its_pending_id(PENDING_SUBSCRIPTION_ID); + std::uint32_t its_remote_subscriber_count(0); +#ifndef VSOMEIP_DISABLE_SECURITY + bool is_internal_policy_update(false); +#endif // !VSOMEIP_DISABLE_SECURITY + std::vector its_buffer(_data, _data + _size); + protocol::error_e its_error; + + auto its_security = policy_manager_impl::get(); + if (!its_security) + return; + + protocol::dummy_command its_dummy_command; + its_dummy_command.deserialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + its_id = its_dummy_command.get_id(); + its_client = its_dummy_command.get_client(); + + bool is_from_routing(false); + if (configuration_->is_security_enabled()) { + if (configuration_->is_local_routing()) { + // if security is enabled, client ID of routing must be configured + // and credential passing is active. Otherwise bound client is zero by default + is_from_routing = (_bound_client == routing_host_id); + } else { + is_from_routing = (_remote_address == configuration_->get_routing_host_address() + && _remote_port == configuration_->get_routing_host_port() + 1); + } + } else { + is_from_routing = (its_client == routing_host_id); + } + + if (configuration_->is_security_enabled() + && configuration_->is_local_routing() + && !is_from_routing && _bound_client != its_client) { + VSOMEIP_WARNING << std::hex << "Client " + << std::setw(4) << std::setfill('0') << get_client() + << " received a message with command " << int(its_id) + << " from " << std::setw(4) << std::setfill('0') + << its_client << " which doesn't match the bound client " + << std::setw(4) << std::setfill('0') << _bound_client + << " ~> skip message!"; + return; + } + + switch (its_id) { + case protocol::id_e::SEND_ID: + { + protocol::send_command its_send_command(protocol::id_e::SEND_ID); + its_send_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + auto a_deserializer = get_deserializer(); + a_deserializer->set_data(its_send_command.get_message()); + std::shared_ptr its_message(a_deserializer->deserialize_message()); + a_deserializer->reset(); + put_deserializer(a_deserializer); + + if (its_message) { + its_message->set_instance(its_send_command.get_instance()); + its_message->set_reliable(its_send_command.is_reliable()); + its_message->set_check_result(its_send_command.get_status()); + if (_sec_client) + its_message->set_sec_client(*_sec_client); + its_message->set_env(get_env(_bound_client)); + + if (!is_from_routing) { + if (utility::is_notification(its_message->get_message_type())) { + if (!is_response_allowed(_bound_client, its_message->get_service(), + its_message->get_instance(), its_message->get_method())) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " received a notification from client 0x" << _bound_client + << " which does not offer service/instance/event " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " ~> Skip message!"; + return; + } else { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " isn't allowed to receive a notification from service/instance/event " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " respectively from client 0x" << _bound_client + << " ~> Skip message!"; + return; + } + cache_event_payload(its_message); + } + } else if (utility::is_request(its_message->get_message_type())) { + if (configuration_->is_security_enabled() + && configuration_->is_local_routing() + && its_message->get_client() != _bound_client) { + VSOMEIP_WARNING << std::hex << "vSomeIP Security: Client 0x" << std::setw(4) << std::setfill('0') << get_client() + << " received a request from client 0x" << std::setw(4) << std::setfill('0') + << its_message->get_client() << " to service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() << " which doesn't match the bound client 0x" + << std::setw(4) << std::setfill('0') << _bound_client + << " ~> skip message!"; + return; + } + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(_sec_client, + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_message->get_client() + << " : routing_manager_client::on_message: " + << "isn't allowed to send a request to service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " ~> Skip message!"; + return; + } + } else { // response + if (!is_response_allowed(_bound_client, its_message->get_service(), + its_message->get_instance(), its_message->get_method())) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " received a response from client 0x" << _bound_client + << " which does not offer service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " ~> Skip message!"; + return; + } else { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " isn't allowed to receive a response from service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " respectively from client 0x" << _bound_client + << " ~> Skip message!"; + return; + } + } + } + } else { + if (!configuration_->is_remote_access_allowed()) { + // if the message is from routing manager, check if + // policy allows remote requests. + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << std::hex << "Security: Remote clients via routing manager with client ID 0x" << its_client + << " are not allowed to communicate with service/instance/method " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " respectively with client 0x" << get_client() + << " ~> Skip message!"; + return; + } else if (utility::is_notification(its_message->get_message_type())) { + // As subscription is sent on eventgroup level, incoming remote event ID's + // need to be checked as well if remote clients are allowed + // and the local policy only allows specific events in the eventgroup to be received. + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " isn't allowed to receive a notification from service/instance/event " + << its_message->get_service() << "/" << its_message->get_instance() + << "/" << its_message->get_method() + << " respectively from remote clients via routing manager with client ID 0x" + << routing_host_id + << " ~> Skip message!"; + return; + } + cache_event_payload(its_message); + } + } + #ifdef USE_DLT + if (client_side_logging_ + && (client_side_logging_filter_.empty() + || (1 == client_side_logging_filter_.count(std::make_tuple(its_message->get_service(), ANY_INSTANCE))) + || (1 == client_side_logging_filter_.count(std::make_tuple(its_message->get_service(), its_message->get_instance()))))) { + trace::header its_header; + if (its_header.prepare(nullptr, false, its_send_command.get_instance())) { + uint32_t its_message_size = its_send_command.get_size(); + if (its_message_size >= uint32_t{vsomeip_v3::protocol::SEND_COMMAND_HEADER_SIZE}) + its_message_size -= uint32_t{vsomeip_v3::protocol::SEND_COMMAND_HEADER_SIZE}; + else + its_message_size = 0; + + tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, + &_data[vsomeip_v3::protocol::SEND_COMMAND_HEADER_SIZE], its_message_size); + } + } + #endif + + host_->on_message(std::move(its_message)); + } else + VSOMEIP_ERROR << "Routing proxy: on_message: " + << "SomeIP-Header deserialization failed!"; + } else + VSOMEIP_ERROR << __func__ + << ": send command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::ASSIGN_CLIENT_ACK_ID: + { + client_t its_assigned_client(VSOMEIP_CLIENT_UNSET); + protocol::assign_client_ack_command its_ack_command; + its_ack_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) + its_assigned_client = its_ack_command.get_assigned(); + + on_client_assign_ack(its_assigned_client); + break; + } + + case protocol::id_e::ROUTING_INFO_ID: + if (!configuration_->is_security_enabled() || is_from_routing) { + on_routing_info(_data, _size); + } else { + VSOMEIP_WARNING << "routing_manager_client::on_message: " + << std::hex << "Security: Client 0x" << get_client() + << " received an routing info from a client which isn't the routing manager" + << " : Skip message!"; + } + break; + + case protocol::id_e::PING_ID: + { + protocol::ping_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + send_pong(); + VSOMEIP_TRACE << "PING(" + << std::hex << std::setw(4) << std::setfill('0') << get_client() << ")"; + } else + VSOMEIP_ERROR << __func__ + << ": ping command deserialization failed (" + << std::dec << int(its_error) << ")"; + break; + } + + case protocol::id_e::SUBSCRIBE_ID: + { + protocol::subscribe_command its_subscribe_command; + its_subscribe_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_service = its_subscribe_command.get_service(); + its_instance = its_subscribe_command.get_instance(); + its_eventgroup = its_subscribe_command.get_eventgroup(); + its_major = its_subscribe_command.get_major(); + its_event = its_subscribe_command.get_event(); + its_pending_id = its_subscribe_command.get_pending_id(); + auto its_filter = its_subscribe_command.get_filter(); + + std::unique_lock its_lock(incoming_subscriptions_mutex_); + if (its_pending_id != PENDING_SUBSCRIPTION_ID) { + its_lock.unlock(); +#ifdef VSOMEIP_ENABLE_COMPAT + routing_manager_base::set_incoming_subscription_state(its_client, its_service, + its_instance, its_eventgroup, its_event, subscription_state_e::IS_SUBSCRIBING); +#endif + // Remote subscriber: Notify routing manager initially + count subscribes + auto self = shared_from_this(); + host_->on_subscription(its_service, its_instance, its_eventgroup, + its_client, _sec_client, get_env(its_client), true, + [this, self, its_client, its_service, its_instance, + its_eventgroup, its_event, its_filter, its_pending_id, its_major] + (const bool _subscription_accepted) { + + std::uint32_t its_count(0); + if (_subscription_accepted) { + send_subscribe_ack(its_client, its_service, its_instance, + its_eventgroup, its_event, its_pending_id); + std::set its_already_subscribed_events; + bool inserted = insert_subscription(its_service, its_instance, its_eventgroup, + its_event, its_filter, VSOMEIP_ROUTING_CLIENT, &its_already_subscribed_events); + if (inserted) { + notify_remote_initially(its_service, its_instance, its_eventgroup, + its_already_subscribed_events); + } + #ifdef VSOMEIP_ENABLE_COMPAT + send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client, true); + #endif + its_count = get_remote_subscriber_count( + its_service, its_instance, its_eventgroup, true); + } else { + send_subscribe_nack(its_client, its_service, its_instance, + its_eventgroup, its_event, its_pending_id); + } + VSOMEIP_INFO << "SUBSCRIBE(" + << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << ":" + << std::hex << std::setw(4) << std::setfill('0') << its_event << ":" + << std::dec << (uint16_t)its_major << "] " + << std::boolalpha << (its_pending_id != PENDING_SUBSCRIPTION_ID) + << " " + << (_subscription_accepted ? + std::to_string(its_count) + " accepted." : "not accepted."); + +#ifdef VSOMEIP_ENABLE_COMPAT + routing_manager_base::erase_incoming_subscription_state(its_client, its_service, + its_instance, its_eventgroup, its_event); +#endif + }); + } else if (is_client_known(its_client)) { + its_lock.unlock(); + if (!is_from_routing) { + if (its_event == ANY_EVENT) { + if (!is_subscribe_to_any_event_allowed(_sec_client, its_client, its_service, its_instance, its_eventgroup)) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client + << " : routing_manager_client::on_message: " + << " isn't allowed to subscribe to service/instance/event " + << its_service << "/" << its_instance << "/ANY_EVENT" + << " which violates the security policy ~> Skip subscribe!"; + return; + } + } else { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member( + _sec_client, its_service, its_instance, its_event)) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client + << " : routing_manager_client::on_message: " + << " subscribes to service/instance/event " + << its_service << "/" << its_instance << "/" << its_event + << " which violates the security policy ~> Skip subscribe!"; + return; + } + } + } else { + if (!configuration_->is_remote_access_allowed()) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client + << " : routing_manager_client::on_message: " + << std::hex << "Routing manager with client ID 0x" + << its_client + << " isn't allowed to subscribe to service/instance/event " + << its_service << "/" << its_instance + << "/" << its_event + << " respectively to client 0x" << get_client() + << " ~> Skip Subscribe!"; + return; + } + } + + // Local & already known subscriber: create endpoint + send (N)ACK + insert subscription +#ifdef VSOMEIP_ENABLE_COMPAT + routing_manager_base::set_incoming_subscription_state(its_client, its_service, + its_instance, its_eventgroup, its_event, subscription_state_e::IS_SUBSCRIBING); +#endif + (void) ep_mgr_->find_or_create_local(its_client); + auto self = shared_from_this(); + auto its_env = get_env(its_client); + host_->on_subscription(its_service, its_instance, + its_eventgroup, its_client, _sec_client, its_env, true, + [this, self, its_client, its_filter, _sec_client, its_env, its_service, + its_instance, its_eventgroup, its_event, its_major] + (const bool _subscription_accepted) { + if (!_subscription_accepted) { + send_subscribe_nack(its_client, its_service, its_instance, + its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID); + } else { + send_subscribe_ack(its_client, its_service, its_instance, + its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID); + routing_manager_base::subscribe(its_client, _sec_client, + its_service, its_instance, its_eventgroup, its_major, its_event, its_filter); +#ifdef VSOMEIP_ENABLE_COMPAT + send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client); +#endif + } +#ifdef VSOMEIP_ENABLE_COMPAT + routing_manager_base::erase_incoming_subscription_state(its_client, its_service, + its_instance, its_eventgroup, its_event); +#endif + }); + } else { + if (_sec_client) { + // Local & not yet known subscriber ~> set pending until subscriber gets known! + subscription_data_t subscription = { + its_service, its_instance, + its_eventgroup, its_major, + its_event, its_filter, + *_sec_client + }; + pending_incoming_subscriptions_[its_client].insert(subscription); + } else { + VSOMEIP_WARNING << __func__ + << ": Local subscription without security info."; + } + } + + if (its_pending_id == PENDING_SUBSCRIPTION_ID) { // local subscription + VSOMEIP_INFO << "SUBSCRIBE(" + << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << ":" + << std::hex << std::setw(4) << std::setfill('0') << its_event << ":" + << std::dec << (uint16_t)its_major << "]"; + } + } else { + VSOMEIP_ERROR << __func__ + << ": subscribe command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + } + break; + } + + case protocol::id_e::UNSUBSCRIBE_ID: + { + protocol::unsubscribe_command its_unsubscribe; + its_unsubscribe.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_unsubscribe.get_client(); + its_service = its_unsubscribe.get_service(); + its_instance = its_unsubscribe.get_instance(); + its_eventgroup = its_unsubscribe.get_eventgroup(); + its_event = its_unsubscribe.get_event(); + its_pending_id = its_unsubscribe.get_pending_id(); + + host_->on_subscription(its_service, its_instance, its_eventgroup, + its_client, _sec_client, get_env(its_client), false, + [](const bool _subscription_accepted){ + (void)_subscription_accepted; + } + ); + if (its_pending_id == PENDING_SUBSCRIPTION_ID) { + // Local subscriber: withdraw subscription + routing_manager_base::unsubscribe(its_client, _sec_client, its_service, its_instance, its_eventgroup, its_event); + } else { + // Remote subscriber: withdraw subscription only if no more remote subscriber exists + its_remote_subscriber_count = get_remote_subscriber_count(its_service, + its_instance, its_eventgroup, false); + if (!its_remote_subscriber_count) { + routing_manager_base::unsubscribe(VSOMEIP_ROUTING_CLIENT, nullptr, its_service, + its_instance, its_eventgroup, its_event); + } + send_unsubscribe_ack(its_service, its_instance, its_eventgroup, its_pending_id); + } + VSOMEIP_INFO << "UNSUBSCRIBE(" + << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << its_event << "] " + << (bool)(its_pending_id != PENDING_SUBSCRIPTION_ID) << " " + << std::dec << its_remote_subscriber_count; + } else + VSOMEIP_ERROR << __func__ + << ": unsubscribe command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::EXPIRE_ID: + { + protocol::expire_command its_expire; + its_expire.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_expire.get_client(); + its_service = its_expire.get_service(); + its_instance = its_expire.get_instance(); + its_eventgroup = its_expire.get_eventgroup(); + its_event = its_expire.get_event(); + its_pending_id = its_expire.get_pending_id(); + + host_->on_subscription(its_service, its_instance, its_eventgroup, its_client, + _sec_client, get_env(its_client), false, + [](const bool _subscription_accepted){ (void)_subscription_accepted; }); + if (its_pending_id == PENDING_SUBSCRIPTION_ID) { + // Local subscriber: withdraw subscription + routing_manager_base::unsubscribe(its_client, _sec_client, + its_service, its_instance, its_eventgroup, its_event); + } else { + // Remote subscriber: withdraw subscription only if no more remote subscriber exists + its_remote_subscriber_count = get_remote_subscriber_count(its_service, + its_instance, its_eventgroup, false); + if (!its_remote_subscriber_count) { + routing_manager_base::unsubscribe(VSOMEIP_ROUTING_CLIENT, nullptr, + its_service, its_instance, its_eventgroup, its_event); + } + } + VSOMEIP_INFO << "EXPIRED SUBSCRIPTION(" + << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << its_event << "] " + << (bool)(its_pending_id != PENDING_SUBSCRIPTION_ID) << " " + << std::dec << its_remote_subscriber_count; + } else + VSOMEIP_ERROR << __func__ + << ": expire deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::SUBSCRIBE_NACK_ID: + { + protocol::subscribe_nack_command its_subscribe_nack; + its_subscribe_nack.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_service = its_subscribe_nack.get_service(); + its_instance = its_subscribe_nack.get_instance(); + its_eventgroup = its_subscribe_nack.get_eventgroup(); + its_subscriber = its_subscribe_nack.get_subscriber(); + its_event = its_subscribe_nack.get_event(); + + on_subscribe_nack(its_subscriber, its_service, its_instance, its_eventgroup, its_event); + VSOMEIP_INFO << "SUBSCRIBE NACK(" + << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << its_event << "]"; + } else + VSOMEIP_ERROR << __func__ + << ": subscribe nack command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::SUBSCRIBE_ACK_ID: + { + protocol::subscribe_ack_command its_subscribe_ack; + its_subscribe_ack.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_service = its_subscribe_ack.get_service(); + its_instance = its_subscribe_ack.get_instance(); + its_eventgroup = its_subscribe_ack.get_eventgroup(); + its_subscriber = its_subscribe_ack.get_subscriber(); + its_event = its_subscribe_ack.get_event(); + + on_subscribe_ack(its_subscriber, its_service, its_instance, its_eventgroup, its_event); + VSOMEIP_INFO << "SUBSCRIBE ACK(" + << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << its_event << "]"; + } else + VSOMEIP_ERROR << __func__ + << ": subscribe ack command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::OFFERED_SERVICES_RESPONSE_ID: + { + protocol::offered_services_response_command its_response; + its_response.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + if (!configuration_->is_security_enabled() || is_from_routing) { + on_offered_services_info(its_response); + } else { + VSOMEIP_WARNING << std::hex << "Security: Client 0x" << get_client() + << " received an offered services info from a client which isn't the routing manager" + << " : Skip message!"; + } + } else + VSOMEIP_ERROR << __func__ + << ": offered services response command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + case protocol::id_e::RESEND_PROVIDED_EVENTS_ID: + { + protocol::resend_provided_events_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + resend_provided_event_registrations(); + send_resend_provided_event_response(its_command.get_remote_offer_id()); + + VSOMEIP_INFO << "RESEND_PROVIDED_EVENTS(" + << std::hex << std::setw(4) << std::setfill('0') + << its_command.get_client() << ")"; + } else + VSOMEIP_ERROR << __func__ + << ": resend provided events command deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + case protocol::id_e::SUSPEND_ID: + { + on_suspend(); // cleanup remote subscribers + break; + } +#ifndef VSOMEIP_DISABLE_SECURITY + case protocol::id_e::UPDATE_SECURITY_POLICY_INT_ID: + is_internal_policy_update = true; + [[gnu::fallthrough]]; + case protocol::id_e::UPDATE_SECURITY_POLICY_ID: + { + if (!configuration_->is_security_enabled() || is_from_routing) { + protocol::update_security_policy_command its_command(is_internal_policy_update); + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + auto its_policy = its_command.get_policy(); + uint32_t its_uid; + uint32_t its_gid; + if (its_policy->get_uid_gid(its_uid, its_gid)) { + if (is_internal_policy_update + || its_security->is_policy_update_allowed(its_uid, its_policy)) { + its_security->update_security_policy(its_uid, its_gid, its_policy); + send_update_security_policy_response(its_command.get_update_id()); + } + } else { + VSOMEIP_ERROR << "vSomeIP Security: Policy has no valid uid/gid!"; + } + } else { + VSOMEIP_ERROR << "vSomeIP Security: Policy deserialization failed!"; + } + } else { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " received a security policy update from a client which isn't the routing manager" + << " : Skip message!"; + } + break; + } + + case protocol::id_e::REMOVE_SECURITY_POLICY_ID: + { + if (!configuration_->is_security_enabled() || is_from_routing) { + protocol::remove_security_policy_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + uid_t its_uid(its_command.get_uid()); + gid_t its_gid(its_command.get_gid()); + + if (its_security->is_policy_removal_allowed(its_uid)) { + its_security->remove_security_policy(its_uid, its_gid); + send_remove_security_policy_response(its_command.get_update_id()); + } + } else + VSOMEIP_ERROR << __func__ + << ": remove security policy command deserialization failed (" + << static_cast(its_error) + << ")"; + } else + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << "received a security policy removal from a client which isn't the routing manager" + << " : Skip message!"; + break; + } + + case protocol::id_e::DISTRIBUTE_SECURITY_POLICIES_ID: + { + if (!configuration_->is_security_enabled() || is_from_routing) { + protocol::distribute_security_policies_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + for (auto p : its_command.get_policies()) { + uid_t its_uid; + gid_t its_gid; + p->get_uid_gid(its_uid, its_gid); + if (its_security->is_policy_update_allowed(its_uid, p)) + its_security->update_security_policy(its_uid, its_gid, p); + } + } else + VSOMEIP_ERROR << __func__ + << ": distribute security policies command deserialization failed (" + << static_cast(its_error) + << ")"; + } else + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << " received a security policy distribution command from a client which isn't the routing manager" + << " : Skip message!"; + break; + } + + case protocol::id_e::UPDATE_SECURITY_CREDENTIALS_ID: + { + if (!configuration_->is_security_enabled() || is_from_routing) { + protocol::update_security_credentials_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + on_update_security_credentials(its_command); + } else + VSOMEIP_ERROR << __func__ + << ": update security credentials command deserialization failed (" + << static_cast(its_error) + << ")"; + } else + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_message: " + << "received a security credential update from a client which isn't the routing manager" + << " : Skip message!"; + + break; + } +#endif // !VSOMEIP_DISABLE_SECURITY + default: + break; + } + } else + VSOMEIP_ERROR << __func__ + << ": dummy command deserialization failed (" + << std::dec << static_cast(its_error) + << ")"; +} + +void routing_manager_client::on_routing_info( + const byte_t *_data, uint32_t _size) { +#if 0 + std::stringstream msg; + msg << "rmp::on_routing_info(" << std::hex << get_client() << "): "; + for (uint32_t i = 0; i < _size; ++i) + msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + auto its_security = policy_manager_impl::get(); + if (!its_security) + return; + + std::vector its_buffer(_data, _data + _size); + protocol::error_e its_error; + + protocol::routing_info_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error != protocol::error_e::ERROR_OK) { + VSOMEIP_ERROR << __func__ + << ": deserializing routing info command failed (" + << static_cast(its_error) + << ")"; + return; + } + + for (const auto &e : its_command.get_entries()) { + auto its_client = e.get_client(); + switch (e.get_type()) { + case protocol::routing_info_entry_type_e::RIE_ADD_CLIENT: + { + auto its_address = e.get_address(); + if (!its_address.is_unspecified()) { + add_guest(its_client, its_address, e.get_port()); + add_known_client(its_client, ""); + } + + if (its_client == get_client()) { + VSOMEIP_INFO << std::hex << "Application/Client " << get_client() + << " (" << host_->get_name() << ") is registered."; +#if defined(__linux__) || defined(ANDROID) + if (!its_security->check_credentials(get_client(), get_sec_client())) { + VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::on_routing_info: RIE_ADD_CLIENT: isn't allowed" + << " to use the server endpoint due to credential check failed!"; + deregister_application(); + host_->on_state(static_cast(inner_state_type_e::ST_DEREGISTERED)); + return; + } +#endif + { + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_REGISTERING) { + boost::system::error_code ec; + register_application_timer_.cancel(ec); + send_registered_ack(); + send_pending_commands(); + state_ = inner_state_type_e::ST_REGISTERED; + // Notify stop() call about clean deregistration + state_condition_.notify_one(); + } + } + + // inform host about its own registration state changes + if (state_ == inner_state_type_e::ST_REGISTERED) { + host_->on_state(static_cast(inner_state_type_e::ST_REGISTERED)); + } + } + break; + } + + case protocol::routing_info_entry_type_e::RIE_DELETE_CLIENT: + { + { + std::lock_guard its_lock(known_clients_mutex_); + known_clients_.erase(its_client); + } + if (its_client == get_client()) { + its_security->remove_client_to_sec_client_mapping(its_client); + VSOMEIP_INFO << std::hex << "Application/Client " << get_client() + << " (" << host_->get_name() << ") is deregistered."; + + // inform host about its own registration state changes + host_->on_state(static_cast(inner_state_type_e::ST_DEREGISTERED)); + + { + std::lock_guard its_lock(state_mutex_); + state_ = inner_state_type_e::ST_DEREGISTERED; + // Notify stop() call about clean deregistration + state_condition_.notify_one(); + } + } else if (its_client != VSOMEIP_ROUTING_CLIENT) { + remove_local(its_client, true); + } + break; + } + + case protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE: + { + auto its_address = e.get_address(); + if (!its_address.is_unspecified()) { + add_guest(its_client, its_address, e.get_port()); + add_known_client(its_client, ""); + } + { + // Add yet unknown clients that offer services. Otherwise, + // the service cannot be used. The entry will be overwritten, + // when the offering clients connects. + std::lock_guard its_lock(known_clients_mutex_); + if (known_clients_.find(its_client) == known_clients_.end()) { + known_clients_[its_client] = ""; + } + } + + for (const auto &s : e.get_services()) { + + const auto its_service(s.service_); + const auto its_instance(s.instance_); + const auto its_major(s.major_); + const auto its_minor(s.minor_); + + { + std::lock_guard its_lock(local_services_mutex_); + + // Check whether the service instance is already known. If yes, + // continue with the next service within the routing info. + auto found_service = local_services_.find(its_service); + if (found_service != local_services_.end()) { + if (found_service->second.find(its_instance) != found_service->second.end()) + continue; + } + + local_services_[its_service][its_instance] + = std::make_tuple(its_major, its_minor, its_client); + } + { + std::lock_guard its_lock(state_mutex_); + send_pending_subscriptions(its_service, its_instance, its_major); + } + host_->on_availability(its_service, its_instance, + availability_state_e::AS_AVAILABLE, its_major, its_minor); + VSOMEIP_INFO << "ON_AVAILABLE(" + << std::hex << std::setw(4) << std::setfill('0') << get_client() <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance + << ":" << std::dec << int(its_major) << "." << std::dec << its_minor << "]"; + } + break; + } + + case protocol::routing_info_entry_type_e::RIE_DELETE_SERVICE_INSTANCE: + { + for (const auto &s : e.get_services()) { + const auto its_service(s.service_); + const auto its_instance(s.instance_); + const auto its_major(s.major_); + const auto its_minor(s.minor_); + + { + std::lock_guard its_lock(local_services_mutex_); + auto found_service = local_services_.find(its_service); + if (found_service != local_services_.end()) { + found_service->second.erase(its_instance); + // move previously offering client to history + local_services_history_[its_service][its_instance].insert(its_client); + if (found_service->second.size() == 0) { + local_services_.erase(its_service); + } + } + } + on_stop_offer_service(its_service, its_instance, its_major, its_minor); + host_->on_availability(its_service, its_instance, + availability_state_e::AS_UNAVAILABLE, its_major, its_minor); + VSOMEIP_INFO << "ON_UNAVAILABLE(" + << std::hex << std::setw(4) << std::setfill('0') << get_client() <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance + << ":" << std::dec << int(its_major) << "." << std::dec << its_minor << "]"; + } + break; + } + + default: + VSOMEIP_ERROR << __func__ + << ": Unknown routing info entry type (" + << static_cast(e.get_type()) + << ")"; + break; + } + } + + { + struct subscription_info { + service_t service_id_; + instance_t instance_id_; + eventgroup_t eventgroup_id_; + client_t client_id_; + major_version_t major_; + event_t event_; + std::shared_ptr filter_; + vsomeip_sec_client_t sec_client_; + std::string env_; + }; + std::lock_guard its_lock(incoming_subscriptions_mutex_); + std::forward_list subscription_actions; + if (pending_incoming_subscriptions_.size()) { + { + std::lock_guard its_lock(known_clients_mutex_); + for (const auto &k : known_clients_) { + auto its_client = pending_incoming_subscriptions_.find(k.first); + if (its_client != pending_incoming_subscriptions_.end()) { + for (const auto &subscription : its_client->second) { + subscription_actions.push_front( + { subscription.service_, subscription.instance_, + subscription.eventgroup_, k.first, + subscription.major_, subscription.event_, + subscription.filter_, + subscription.sec_client_, + get_env_unlocked(k.first)}); + } + } + } + } + for (const subscription_info &si : subscription_actions) { +#ifdef VSOMEIP_ENABLE_COMPAT + routing_manager_base::set_incoming_subscription_state(si.client_id_, si.service_id_, si.instance_id_, + si.eventgroup_id_, si.event_, subscription_state_e::IS_SUBSCRIBING); +#endif + (void) ep_mgr_->find_or_create_local(si.client_id_); + auto self = shared_from_this(); + host_->on_subscription( + si.service_id_, si.instance_id_, si.eventgroup_id_, + si.client_id_, &si.sec_client_, si.env_, true, + [this, self, si](const bool _subscription_accepted) { + if (!_subscription_accepted) { + send_subscribe_nack(si.client_id_, si.service_id_, + si.instance_id_, si.eventgroup_id_, si.event_, PENDING_SUBSCRIPTION_ID); + } else { + send_subscribe_ack(si.client_id_, si.service_id_, + si.instance_id_, si.eventgroup_id_, si.event_, PENDING_SUBSCRIPTION_ID); + routing_manager_base::subscribe(si.client_id_, &si.sec_client_, + si.service_id_, si.instance_id_, si.eventgroup_id_, + si.major_, si.event_, si.filter_); +#ifdef VSOMEIP_ENABLE_COMPAT + send_pending_notify_ones(si.service_id_, + si.instance_id_, si.eventgroup_id_, si.client_id_); +#endif + } +#ifdef VSOMEIP_ENABLE_COMPAT + routing_manager_base::erase_incoming_subscription_state(si.client_id_, si.service_id_, + si.instance_id_, si.eventgroup_id_, si.event_); +#endif + { + std::lock_guard its_lock2(incoming_subscriptions_mutex_); + pending_incoming_subscriptions_.erase(si.client_id_); + } + }); + } + } + } +} + +void routing_manager_client::on_offered_services_info( + protocol::offered_services_response_command &_command) { + + std::vector> its_offered_services_info; + + for (const auto &s : _command.get_services()) + its_offered_services_info.push_back(std::make_pair(s.service_, s.instance_)); + + host_->on_offered_services_info(its_offered_services_info); +} + +void routing_manager_client::reconnect(const std::map &_clients) { + auto its_security = policy_manager_impl::get(); + if (!its_security) + return; + + // inform host about its own registration state changes + host_->on_state(static_cast(inner_state_type_e::ST_DEREGISTERED)); + + { + std::lock_guard its_lock(state_mutex_); + state_ = inner_state_type_e::ST_DEREGISTERED; + // Notify stop() call about clean deregistration + state_condition_.notify_one(); + } + + + // Remove all local connections/endpoints + for (const auto &c : _clients) { + if (c.first != VSOMEIP_ROUTING_CLIENT) { + remove_local(c.first, true); + } + } + + VSOMEIP_INFO << std::hex << "Application/Client " << get_client() + <<": Reconnecting to routing manager."; + +#if defined(__linux__) || defined(ANDROID) + if (!its_security->check_credentials(get_client(), get_sec_client())) { + VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() + << " : routing_manager_client::reconnect: isn't allowed" + << " to use the server endpoint due to credential check failed!"; + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->stop(); + } + return; + } +#endif + + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->restart(); + } +} + +void routing_manager_client::assign_client() { + + protocol::assign_client_command its_command; + its_command.set_client(get_client()); + its_command.set_name(host_->get_name()); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error != protocol::error_e::ERROR_OK) { + + VSOMEIP_ERROR << __func__ << ": command creation failed (" + << std::dec << static_cast(its_error) << ")"; + return; + } + + std::lock_guard its_state_lock(state_mutex_); + if (is_connected_) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + if (state_ != inner_state_type_e::ST_DEREGISTERED) + return; + state_ = inner_state_type_e::ST_ASSIGNING; + + sender_->send(&its_buffer[0], static_cast(its_buffer.size())); + + boost::system::error_code ec; + register_application_timer_.cancel(ec); + register_application_timer_.expires_from_now(std::chrono::milliseconds(10000)); + register_application_timer_.async_wait( + std::bind( + &routing_manager_client::assign_client_timeout_cbk, + std::dynamic_pointer_cast(shared_from_this()), + std::placeholders::_1)); + } + } +} + +void routing_manager_client::register_application() { + + if (!receiver_) { + VSOMEIP_ERROR << __func__ + << "Cannot register. Local server endpoint does not exist."; + return; + } + + auto its_configuration(get_configuration()); + if (its_configuration->is_local_routing()) { + VSOMEIP_INFO << "Registering to routing manager @ " + << its_configuration->get_network() << "-0"; + } else { + auto its_routing_address(its_configuration->get_routing_host_address()); + auto its_routing_port(its_configuration->get_routing_host_port()); + VSOMEIP_INFO << "Registering to routing manager @ " + << its_routing_address.to_string() << ":" << its_routing_port; + } + + protocol::register_application_command its_command; + its_command.set_client(get_client()); + its_command.set_port(receiver_->get_local_port()); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + if (is_connected_) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + state_ = inner_state_type_e::ST_REGISTERING; + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + + register_application_timer_.cancel(); + register_application_timer_.expires_from_now(std::chrono::milliseconds(1000)); + register_application_timer_.async_wait( + std::bind( + &routing_manager_client::register_application_timeout_cbk, + std::dynamic_pointer_cast(shared_from_this()), + std::placeholders::_1)); + } + } + } else + VSOMEIP_ERROR << __func__ + << ": register application command serialization failed(" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::deregister_application() { + + protocol::deregister_application_command its_command; + its_command.set_client(get_client()); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + if (is_connected_) + { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } else + VSOMEIP_ERROR << __func__ + << ": deregister application command serialization failed(" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::send_pong() const { + + protocol::pong_command its_command; + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + if (is_connected_) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } + } else + VSOMEIP_ERROR << __func__ + << ": pong command serialization failed(" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::send_request_services(const std::set &_requests) { + + if (!_requests.size()) { + return; + } + + protocol::request_service_command its_command; + its_command.set_client(get_client()); + its_command.set_services(_requests); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else { + VSOMEIP_ERROR << __func__ << ": request service serialization failed (" + << std::dec << static_cast(its_error) << ")"; + } +} + +void routing_manager_client::send_release_service(client_t _client, service_t _service, + instance_t _instance) { + + (void)_client; + + protocol::release_service_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } +} + +void routing_manager_client::send_pending_event_registrations(client_t _client) { + + protocol::register_events_command its_command; + its_command.set_client(_client); + std::set::iterator it = pending_event_registrations_.begin(); + + while(it != pending_event_registrations_.end()) + { + for(; it!=pending_event_registrations_.end(); it++) { + protocol::register_event reg(it->service_, it->instance_, it->notifier_, it->type_, + it->is_provided_, it->reliability_, it->is_cyclic_ + , (uint16_t)it->eventgroups_.size(), it->eventgroups_); + if(!its_command.add_registration(reg)) {break;} + } + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": register event command serialization failed (" + << std::dec << int(its_error) << ")"; + } +} + +void routing_manager_client::send_register_event(client_t _client, + service_t _service, instance_t _instance, + event_t _notifier, + const std::set &_eventgroups, const event_type_e _type, + reliability_type_e _reliability, + bool _is_provided, bool _is_cyclic) { + + (void)_client; + + protocol::register_events_command its_command; + its_command.set_client(get_client()); + + protocol::register_event reg(_service, _instance, _notifier, _type, + _is_provided, _reliability, _is_cyclic, + (uint16_t)_eventgroups.size(), _eventgroups); + + if(!its_command.add_registration(reg)) { + VSOMEIP_ERROR << __func__ << ": register event command is too long."; + } + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + + if (_is_provided) { + VSOMEIP_INFO << "REGISTER EVENT(" + << std::hex << std::setw(4) << std::setfill('0') << get_client() << "): [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _notifier + << ":is_provider=" << std::boolalpha << _is_provided << "]"; + } + } else + VSOMEIP_ERROR << __func__ + << ": register event command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::on_subscribe_ack(client_t _client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { + (void)_client; +#if 0 + VSOMEIP_ERROR << "routing_manager_client::" << __func__ + << "(" << std::hex << host_->get_client() << "):" + << "event=" + << std::hex << _service << "." + << std::hex << _instance << "." + << std::hex << _eventgroup << "." + << std::hex << _event; +#endif + if (_event == ANY_EVENT) { + auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); + if (its_eventgroup) { + for (const auto& its_event : its_eventgroup->get_events()) { + host_->on_subscription_status(_service, _instance, _eventgroup, its_event->get_event(), 0x0 /*OK*/); + } + } + } else { + host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /*OK*/); + } +} + +void routing_manager_client::on_subscribe_nack(client_t _client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { + (void)_client; + if (_event == ANY_EVENT) { + auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); + if (its_eventgroup) { + for (const auto& its_event : its_eventgroup->get_events()) { + host_->on_subscription_status(_service, _instance, _eventgroup, its_event->get_event(), 0x7 /*Rejected*/); + } + } + } else { + host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x7 /*Rejected*/); + } +} + +void routing_manager_client::cache_event_payload( + const std::shared_ptr &_message) { + const service_t its_service(_message->get_service()); + const instance_t its_instance(_message->get_instance()); + const method_t its_method(_message->get_method()); + std::shared_ptr its_event = find_event(its_service, its_instance, its_method); + if (its_event) { + if (its_event->is_field()) { + its_event->prepare_update_payload(_message->get_payload(), true); + its_event->update_payload(); + } + } else { + // we received a event which was not yet requested + std::set its_eventgroups; + // create a placeholder field until someone requests this event with + // full information like eventgroup, field or not etc. + routing_manager_base::register_event(host_->get_client(), + its_service, its_instance, + its_method, + its_eventgroups, event_type_e::ET_UNKNOWN, + reliability_type_e::RT_UNKNOWN, + std::chrono::milliseconds::zero(), false, true, + nullptr, + false, false, true); + std::shared_ptr its_event = find_event(its_service, its_instance, its_method); + if (its_event) { + its_event->prepare_update_payload(_message->get_payload(), true); + its_event->update_payload(); + } + } +} + +void routing_manager_client::on_stop_offer_service(service_t _service, + instance_t _instance, + major_version_t _major, + minor_version_t _minor) { + (void) _major; + (void) _minor; + std::map > events; + { + std::lock_guard its_lock(events_mutex_); + auto its_events_service = events_.find(_service); + if (its_events_service != events_.end()) { + auto its_events_instance = its_events_service->second.find(_instance); + if (its_events_instance != its_events_service->second.end()) { + for (auto &e : its_events_instance->second) + events[e.first] = e.second; + } + } + } + for (auto &e : events) { + e.second->unset_payload(); + } +} + +void routing_manager_client::send_pending_commands() { + for (auto &po : pending_offers_) + send_offer_service(get_client(), + po.service_, po.instance_, + po.major_, po.minor_); + + send_pending_event_registrations(get_client()); + + send_request_services(requests_); +} + +void routing_manager_client::init_receiver() { +#if defined(__linux__) || defined(ANDROID) + auto its_security = policy_manager_impl::get(); + if (!its_security) + return; + + its_security->store_client_to_sec_client_mapping(get_client(), get_sec_client()); + its_security->store_sec_client_to_client_mapping(get_sec_client(), get_client()); +#endif + if (!receiver_) { + receiver_ = ep_mgr_->create_local_server(shared_from_this()); + } else { + std::uint16_t its_port = receiver_->get_local_port(); + if (its_port != ILLEGAL_PORT) + VSOMEIP_INFO << "Reusing local server endpoint@" << its_port; + } +} + +void routing_manager_client::notify_remote_initially(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, const std::set &_events_to_exclude) { + auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); + if (its_eventgroup) { + auto service_info = find_service(_service, _instance); + for (const auto &e : its_eventgroup->get_events()) { + if (e->is_field() && e->is_set() + && _events_to_exclude.find(e->get_event()) + == _events_to_exclude.end()) { + std::shared_ptr its_notification + = runtime::get()->create_notification(); + its_notification->set_service(_service); + its_notification->set_instance(_instance); + its_notification->set_method(e->get_event()); + its_notification->set_payload(e->get_payload()); + if (service_info) { + its_notification->set_interface_version(service_info->get_major()); + } + + std::shared_ptr its_serializer(get_serializer()); + if (its_serializer->serialize(its_notification.get())) { + { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + send_local(sender_, VSOMEIP_ROUTING_CLIENT, + its_serializer->get_data(), its_serializer->get_size(), + _instance, false, protocol::id_e::NOTIFY_ID, 0); + } + } + its_serializer->reset(); + put_serializer(its_serializer); + } else { + VSOMEIP_ERROR << "Failed to serialize message. Check message size!"; + } + } + } + } + +} + +uint32_t routing_manager_client::get_remote_subscriber_count(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, bool _increment) { + std::lock_guard its_lock(remote_subscriber_count_mutex_); + uint32_t count (0); + bool found(false); + auto found_service = remote_subscriber_count_.find(_service); + if (found_service != remote_subscriber_count_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + auto found_group = found_instance->second.find(_eventgroup); + if (found_group != found_instance->second.end()) { + found = true; + if (_increment) { + found_group->second = found_group->second + 1; + } else { + if (found_group->second > 0) { + found_group->second = found_group->second - 1; + } + } + count = found_group->second; + } + } + } + if (!found) { + if (_increment) { + remote_subscriber_count_[_service][_instance][_eventgroup] = 1; + count = 1; + } + } + return count; +} + +void routing_manager_client::clear_remote_subscriber_count( + service_t _service, instance_t _instance) { + std::lock_guard its_lock(remote_subscriber_count_mutex_); + auto found_service = remote_subscriber_count_.find(_service); + if (found_service != remote_subscriber_count_.end()) { + if (found_service->second.erase(_instance)) { + if (!found_service->second.size()) { + remote_subscriber_count_.erase(found_service); + } + } + } +} + +void +routing_manager_client::assign_client_timeout_cbk( + boost::system::error_code const &_error) { + + if (!_error) { + bool register_again(false); + { + std::lock_guard its_lock(state_mutex_); + if (state_ != inner_state_type_e::ST_REGISTERED) { + state_ = inner_state_type_e::ST_DEREGISTERED; + register_again = true; + } + } + if (register_again) { + std::lock_guard its_lock(sender_mutex_); + VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() + << " request client timeout! Trying again..."; + + if (sender_) { + sender_->restart(); + } + } + } +} + +void routing_manager_client::register_application_timeout_cbk( + boost::system::error_code const &_error) { + + bool register_again(false); + { + std::lock_guard its_lock(state_mutex_); + if (!_error && state_ != inner_state_type_e::ST_REGISTERED) { + state_ = inner_state_type_e::ST_DEREGISTERED; + register_again = true; + } + } + if (register_again) { + std::lock_guard its_lock(sender_mutex_); + VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() + << " register timeout! Trying again..."; + + if (sender_) + sender_->restart(); + } +} + +void routing_manager_client::send_registered_ack() { + + protocol::registered_ack_command its_command; + its_command.set_client(get_client()); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": registered ack command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +bool routing_manager_client::is_client_known(client_t _client) { + + std::lock_guard its_lock(known_clients_mutex_); + return (known_clients_.find(_client) != known_clients_.end()); +} + +bool routing_manager_client::create_placeholder_event_and_subscribe( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _notifier, const std::shared_ptr &_filter, + client_t _client) { + + std::lock_guard its_lock(stop_mutex_); + + bool is_inserted(false); + + if (find_service(_service, _instance)) { + // We received an event for an existing service which was not yet + // requested/offered. Create a placeholder field until someone + // requests/offers this event with full information like eventgroup, + // field/event, etc. + std::set its_eventgroups({ _eventgroup }); + // routing_manager_client: Always register with own client id and shadow = false + routing_manager_base::register_event(host_->get_client(), + _service, _instance, _notifier, + its_eventgroups, event_type_e::ET_UNKNOWN, reliability_type_e::RT_UNKNOWN, + std::chrono::milliseconds::zero(), false, true, nullptr, false, false, + true); + + std::shared_ptr its_event = find_event(_service, _instance, _notifier); + if (its_event) { + is_inserted = its_event->add_subscriber(_eventgroup, _filter, _client, false); + } + } + + return is_inserted; +} + +void routing_manager_client::request_debounce_timeout_cbk( + boost::system::error_code const &_error) { + + std::lock_guard its_lock(state_mutex_); + if (!_error) { + if (requests_to_debounce_.size()) { + if (state_ == inner_state_type_e::ST_REGISTERED) { + send_request_services(requests_to_debounce_); + requests_.insert(requests_to_debounce_.begin(), + requests_to_debounce_.end()); + requests_to_debounce_.clear(); + } else { + { + std::lock_guard its_lock(request_timer_mutex_); + request_debounce_timer_running_ = true; + request_debounce_timer_.expires_from_now(std::chrono::milliseconds( + configuration_->get_request_debouncing(host_->get_name()))); + request_debounce_timer_.async_wait( + std::bind( + &routing_manager_client::request_debounce_timeout_cbk, + std::dynamic_pointer_cast(shared_from_this()), + std::placeholders::_1)); + return; + } + } + } + } + { + std::lock_guard its_lock(request_timer_mutex_); + request_debounce_timer_running_ = false; + } +} + +void routing_manager_client::register_client_error_handler(client_t _client, + const std::shared_ptr &_endpoint) { + + _endpoint->register_error_handler( + std::bind(&routing_manager_client::handle_client_error, this, _client)); +} + +void routing_manager_client::handle_client_error(client_t _client) { + + if (_client != VSOMEIP_ROUTING_CLIENT) { + VSOMEIP_INFO << "Client 0x" << std::hex << get_client() + << " handles a client error(" << std::hex << _client << ")"; + remove_local(_client, true); + } else { + bool should_reconnect(true); + { + std::unique_lock its_lock(state_mutex_); + should_reconnect = is_started_; + } + if (should_reconnect) { + std::map its_known_clients; + { + std::lock_guard its_lock(known_clients_mutex_); + its_known_clients = known_clients_; + } + reconnect(its_known_clients); + } + } +} + +void routing_manager_client::send_get_offered_services_info(client_t _client, offer_type_e _offer_type) { + + protocol::offered_services_request_command its_command; + its_command.set_client(_client); + its_command.set_offer_type(_offer_type); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": offered service request command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::send_unsubscribe_ack( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + remote_subscription_id_t _id) { + + protocol::unsubscribe_ack_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_pending_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": unsubscribe ack command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::resend_provided_event_registrations() { + std::lock_guard its_lock(state_mutex_); + for (const event_data_t& ed : pending_event_registrations_) { + if (ed.is_provided_) { + send_register_event(get_client(), ed.service_, ed.instance_, + ed.notifier_, ed.eventgroups_, ed.type_, ed.reliability_, + ed.is_provided_, ed.is_cyclic_); + } + } +} + +void routing_manager_client::send_resend_provided_event_response(pending_remote_offer_id_t _id) { + + protocol::resend_provided_events_command its_command; + its_command.set_client(get_client()); + its_command.set_remote_offer_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": resend provided event command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +#ifndef VSOMEIP_DISABLE_SECURITY +void routing_manager_client::send_update_security_policy_response( + pending_security_update_id_t _update_id) { + + protocol::update_security_policy_response_command its_command; + its_command.set_client(get_client()); + its_command.set_update_id(_update_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": update security policy response command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::send_remove_security_policy_response( + pending_security_update_id_t _update_id) { + + protocol::remove_security_policy_response_command its_command; + its_command.set_client(get_client()); + its_command.set_update_id(_update_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::lock_guard its_lock(sender_mutex_); + if (sender_) { + sender_->send(&its_buffer[0], uint32_t(its_buffer.size())); + } + } else + VSOMEIP_ERROR << __func__ + << ": update security policy response command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +void routing_manager_client::on_update_security_credentials( + const protocol::update_security_credentials_command &_command) { + + auto its_security = policy_manager_impl::get(); + if (!its_security) + return; + + for (const auto &c : _command.get_credentials()) { + std::shared_ptr its_policy(std::make_shared()); + boost::icl::interval_set its_gid_set; + uid_t its_uid(c.first); + gid_t its_gid(c.second); + + its_gid_set.insert(its_gid); + + its_policy->credentials_ += std::make_pair( + boost::icl::interval::closed(its_uid, its_uid), its_gid_set); + its_policy->allow_who_ = true; + its_policy->allow_what_ = true; + + its_security->add_security_credentials(its_uid, its_gid, its_policy, get_client()); + } +} +#endif + +void routing_manager_client::on_client_assign_ack(const client_t &_client) { + + std::lock_guard its_lock(state_mutex_); + if (state_ == inner_state_type_e::ST_ASSIGNING) { + if (_client != VSOMEIP_CLIENT_UNSET) { + state_ = inner_state_type_e::ST_ASSIGNED; + + boost::system::error_code ec; + register_application_timer_.cancel(ec); + host_->set_client(_client); + + if (is_started_) { + init_receiver(); + if (receiver_) { + receiver_->start(); + + VSOMEIP_INFO << std::hex << "Client " << get_client() + << " (" << host_->get_name() + << ") successfully connected to routing ~> registering.."; + register_application(); + } else { + state_ = inner_state_type_e::ST_DEREGISTERED; + + host_->set_client(VSOMEIP_CLIENT_UNSET); + + sender_->restart(); + } + } + } else { + VSOMEIP_ERROR << "Didn't receive valid clientID! Won't register application."; + } + } else { + VSOMEIP_WARNING << "Client " << std::hex << get_client() + << " received another client identifier (" + << std::hex << _client + << "). Ignoring it. (" + << (int)state_ << ")"; + } +} + +void routing_manager_client::on_suspend() { + + VSOMEIP_INFO << __func__ << ": Application " + << std::hex << std::setw(4) << std::setfill('0') + << host_->get_client(); + + std::lock_guard its_lock(remote_subscriber_count_mutex_); + + // Unsubscribe everything that is left over. + for (const auto &s : remote_subscriber_count_) { + for (const auto &i : s.second) { + for (const auto &e : i.second) + routing_manager_base::unsubscribe( + VSOMEIP_ROUTING_CLIENT, nullptr, + s.first, i.first, e.first, ANY_EVENT); + } + } + + // Remove all entries. + remote_subscriber_count_.clear(); +} + +} // namespace vsomeip_v3 diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index 07c0740..4ebca55 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,8 +8,9 @@ #include #include #include +#include -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #include #include @@ -30,10 +31,7 @@ #include "../include/routing_manager_stub.hpp" #include "../include/serviceinfo.hpp" #include "../../configuration/include/configuration.hpp" -#include "../../security/include/security.hpp" - #include "../../endpoints/include/endpoint_definition.hpp" -#include "../../endpoints/include/local_client_endpoint_impl.hpp" #include "../../endpoints/include/tcp_client_endpoint_impl.hpp" #include "../../endpoints/include/tcp_server_endpoint_impl.hpp" #include "../../endpoints/include/udp_client_endpoint_impl.hpp" @@ -42,13 +40,15 @@ #include "../../message/include/deserializer.hpp" #include "../../message/include/message_impl.hpp" #include "../../message/include/serializer.hpp" +#include "../../plugin/include/plugin_manager_impl.hpp" +#include "../../protocol/include/protocol.hpp" +#include "../../security/include/security.hpp" #include "../../service_discovery/include/constants.hpp" #include "../../service_discovery/include/defines.hpp" #include "../../service_discovery/include/runtime.hpp" #include "../../service_discovery/include/service_discovery.hpp" #include "../../utility/include/byteorder.hpp" #include "../../utility/include/utility.hpp" -#include "../../plugin/include/plugin_manager_impl.hpp" #ifdef USE_DLT #include "../../tracing/include/connector_impl.hpp" #endif @@ -89,11 +89,11 @@ routing_manager_impl::routing_manager_impl(routing_manager_host *_host) : } routing_manager_impl::~routing_manager_impl() { - utility::remove_lockfile(configuration_); - utility::reset_client_ids(); + utility::remove_lockfile(configuration_->get_network()); + utility::reset_client_ids(configuration_->get_network()); } -boost::asio::io_service & routing_manager_impl::get_io() { +boost::asio::io_context &routing_manager_impl::get_io() { return routing_manager_base::get_io(); } @@ -101,6 +101,34 @@ client_t routing_manager_impl::get_client() const { return routing_manager_base::get_client(); } +const vsomeip_sec_client_t *routing_manager_impl::get_sec_client() const { + + return (routing_manager_base::get_sec_client()); +} + +std::string routing_manager_impl::get_client_host() const { + return routing_manager_base::get_client_host(); +} + +void routing_manager_impl::set_client_host(const std::string &_client_host) { + routing_manager_base::set_client_host(_client_host); +} + +std::string routing_manager_impl::get_env(client_t _client) const { + + std::lock_guard its_known_clients_lock(known_clients_mutex_); + return get_env_unlocked(_client); +} + +std::string routing_manager_impl::get_env_unlocked(client_t _client) const { + + auto find_client = known_clients_.find(_client); + if (find_client != known_clients_.end()) { + return (find_client->second); + } + return ""; +} + std::set routing_manager_impl::find_local_clients(service_t _service, instance_t _instance) { return routing_manager_base::find_local_clients(_service, _instance); } @@ -109,18 +137,31 @@ client_t routing_manager_impl::find_local_client(service_t _service, instance_t return routing_manager_base::find_local_client(_service, _instance); } -bool routing_manager_impl::is_subscribe_to_any_event_allowed(credentials_t _credentials, client_t _client, +bool routing_manager_impl::is_subscribe_to_any_event_allowed( + const vsomeip_sec_client_t *_sec_client, client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup) { - return routing_manager_base::is_subscribe_to_any_event_allowed(_credentials, _client, + + return routing_manager_base::is_subscribe_to_any_event_allowed(_sec_client, _client, _service, _instance, _eventgroup); } +void routing_manager_impl::add_known_client(client_t _client, const std::string &_client_host) { + routing_manager_base::add_known_client(_client, _client_host); +} + +bool routing_manager_impl::is_routing_manager() const { + return true; +} + void routing_manager_impl::init() { routing_manager_base::init(ep_mgr_impl_); - // TODO: Only instantiate the stub if needed - stub_ = std::make_shared(this, configuration_); - stub_->init(); + if (configuration_->is_routing_enabled()) { + stub_ = std::make_shared(this, configuration_); + stub_->init(); + } else { + VSOMEIP_INFO << "Internal message routing disabled!"; + } if (configuration_->is_sd_enabled()) { VSOMEIP_INFO<< "Service Discovery enabled. Trying to load module."; @@ -162,7 +203,7 @@ void routing_manager_impl::init() { } void routing_manager_impl::start() { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) boost::asio::ip::address its_multicast; try { its_multicast = boost::asio::ip::address::from_string(configuration_->get_sd_multicast()); @@ -172,6 +213,20 @@ void routing_manager_impl::start() { << "\". Please check your configuration."; } + std::stringstream its_netmask_or_prefix; + auto its_unicast = configuration_->get_unicast_address(); + if (its_unicast.is_v4()) + its_netmask_or_prefix << "netmask:" << configuration_->get_netmask().to_string(); + else + its_netmask_or_prefix << "prefix:" << configuration_->get_prefix(); + + VSOMEIP_INFO << "Client [" + << std::hex << std::setw(4) << std::setfill('0') + << get_client() + << "] routes unicast:" << its_unicast.to_string() + << ", " + << its_netmask_or_prefix.str(); + netlink_connector_ = std::make_shared( host_->get_io(), configuration_->get_unicast_address(), its_multicast); netlink_connector_->register_net_if_changes_handler( @@ -185,7 +240,8 @@ void routing_manager_impl::start() { } #endif - stub_->start(); + if (stub_) + stub_->start(); host_->on_state(state_type_e::ST_REGISTERED); if (configuration_->log_version()) { @@ -195,7 +251,7 @@ void routing_manager_impl::start() { version_log_timer_.async_wait(std::bind(&routing_manager_impl::log_version_timer_cbk, this, std::placeholders::_1)); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) if (configuration_->log_memory()) { std::lock_guard its_lock(memory_log_timer_mutex_); boost::system::error_code ec; @@ -231,7 +287,7 @@ void routing_manager_impl::stop() { std::lock_guard its_lock(local_services_mutex_); for (const auto& s : local_services_) { for (const auto& i : s.second) { - if (std::get<2>(i.second) == client_) { + if (std::get<2>(i.second) == get_client()) { its_services[s.first][i.first] = i.second; } } @@ -249,7 +305,7 @@ void routing_manager_impl::stop() { std::lock_guard its_lock(version_log_timer_mutex_); version_log_timer_.cancel(); } -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) { boost::system::error_code ec; std::lock_guard its_lock(memory_log_timer_mutex_); @@ -276,9 +332,10 @@ void routing_manager_impl::stop() { if (discovery_) discovery_->stop(); - stub_->stop(); + if (stub_) + stub_->stop(); - for (const auto& client : ep_mgr_->get_connected_clients()) { + for (const auto client : ep_mgr_->get_connected_clients()) { if (client != VSOMEIP_ROUTING_CLIENT) { remove_local(client, true); } @@ -317,7 +374,7 @@ bool routing_manager_impl::erase_offer_command(service_t _service, instance_t _i if (!found_service_instance->second.empty()) { // check for other commands to be processed auto its_command = found_service_instance->second.front(); - if (std::get<0>(its_command) == VSOMEIP_OFFER_SERVICE) { + if (std::get<0>(its_command) == uint8_t(protocol::id_e::OFFER_SERVICE_ID)) { io_.post([&, its_command, _service, _instance](){ offer_service(std::get<1>(its_command), _service, _instance, std::get<2>(its_command), std::get<3>(its_command), false); @@ -355,7 +412,8 @@ bool routing_manager_impl::offer_service(client_t _client, // only queue commands if method was NOT called via erase_offer_command() if (_must_queue) { - if (!insert_offer_command(_service, _instance, VSOMEIP_OFFER_SERVICE, + if (!insert_offer_command(_service, _instance, + uint8_t(protocol::id_e::OFFER_SERVICE_ID), _client, _major, _minor)) { return false; } @@ -364,15 +422,8 @@ bool routing_manager_impl::offer_service(client_t _client, // Check if the application hosted by routing manager is allowed to offer // offer_service requests of local proxies are checked in rms::on:message if (_client == get_client()) { -#ifdef _WIN32 - std::uint32_t its_routing_uid = ANY_UID; - std::uint32_t its_routing_gid = ANY_GID; -#else - std::uint32_t its_routing_uid = getuid(); - std::uint32_t its_routing_gid = getgid(); -#endif - if (!security::get()->is_offer_allowed(its_routing_uid, its_routing_gid, - _client, _service, _instance)) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_offer( + get_sec_client(), _service, _instance)) { VSOMEIP_WARNING << "routing_manager_impl::offer_service: " << std::hex << "Security: Client 0x" << _client << " isn't allowed to offer the following service/instance " @@ -412,7 +463,8 @@ bool routing_manager_impl::offer_service(client_t _client, && ps.instance_ == _instance && ps.major_ == _major) { insert_subscription(ps.service_, ps.instance_, - ps.eventgroup_, ps.event_, client_, &its_already_subscribed_events); + ps.eventgroup_, ps.event_, nullptr, + get_client(), &its_already_subscribed_events); #if 0 VSOMEIP_ERROR << __func__ << ": event=" @@ -425,8 +477,9 @@ bool routing_manager_impl::offer_service(client_t _client, send_pending_subscriptions(_service, _instance, _major); } - stub_->on_offer_service(_client, _service, _instance, _major, _minor); - on_availability(_service, _instance, true, _major, _minor); + if (stub_) + stub_->on_offer_service(_client, _service, _instance, _major, _minor); + on_availability(_service, _instance, availability_state_e::AS_AVAILABLE, _major, _minor); erase_offer_command(_service, _instance); return true; } @@ -451,7 +504,8 @@ void routing_manager_impl::stop_offer_service(client_t _client, << " (" << std::boolalpha << _must_queue << ")"; if (_must_queue) { - if (!insert_offer_command(_service, _instance, VSOMEIP_STOP_OFFER_SERVICE, + if (!insert_offer_command(_service, _instance, + uint8_t(protocol::id_e::STOP_OFFER_SERVICE_ID), _client, _major, _minor)) { return; } @@ -476,8 +530,9 @@ void routing_manager_impl::stop_offer_service(client_t _client, } on_stop_offer_service(_client, _service, _instance, _major, _minor); - stub_->on_stop_offer_service(_client, _service, _instance, _major, _minor); - on_availability(_service, _instance, false, _major, _minor); + if (stub_) + stub_->on_stop_offer_service(_client, _service, _instance, _major, _minor); + on_availability(_service, _instance, availability_state_e::AS_UNAVAILABLE, _major, _minor); } else { VSOMEIP_WARNING << __func__ << " received STOP_OFFER(" << std::hex << std::setw(4) << std::setfill('0') << _client <<"): [" @@ -503,7 +558,7 @@ void routing_manager_impl::request_service(client_t _client, service_t _service, auto its_info = find_service(_service, _instance); if (!its_info) { - requested_service_add(_client, _service, _instance, _major, _minor); + add_requested_service(_client, _service, _instance, _major, _minor); if (discovery_) { if (!configuration_->is_local_service(_service, _instance)) { // Non local service instance ~> tell SD to find it! @@ -525,7 +580,7 @@ void routing_manager_impl::request_service(client_t _client, service_t _service, || DEFAULT_MINOR == its_info->get_minor() || _minor == ANY_MINOR)) { if(!its_info->is_local()) { - requested_service_add(_client, _service, _instance, _major, _minor); + add_requested_service(_client, _service, _instance, _major, _minor); if (discovery_) { // Non local service instance ~> tell SD to find it! discovery_->request_service(_service, _instance, _major, @@ -538,12 +593,15 @@ void routing_manager_impl::request_service(client_t _client, service_t _service, } if (_client == get_client()) { - stub_->create_local_receiver(); + if (stub_) + stub_->create_local_receiver(); + + protocol::service its_request(_service, _instance, _major, _minor); + std::set requests; + requests.insert(its_request); - service_data_t request = { _service, _instance, _major, _minor }; - std::set requests; - requests.insert(request); - stub_->handle_requests(_client, requests); + if (stub_) + stub_->handle_requests(_client, requests); } } @@ -560,7 +618,7 @@ void routing_manager_impl::release_service(client_t _client, service_t _service, remove_pending_subscription(_service, _instance, 0xFFFF, ANY_EVENT); } routing_manager_base::release_service(_client, _service, _instance); - requested_service_remove(_client, _service, _instance); + remove_requested_service(_client, _service, _instance, ANY_MAJOR, ANY_MINOR); std::shared_ptr its_info(find_service(_service, _instance)); if (its_info && !its_info->is_local()) { @@ -582,9 +640,11 @@ void routing_manager_impl::release_service(client_t _client, service_t _service, } } -void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, event_t _event) { +void routing_manager_impl::subscribe( + client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const std::shared_ptr &_filter) { VSOMEIP_INFO << "SUBSCRIBE(" << std::hex << std::setw(4) << std::setfill('0') << _client <<"): [" @@ -600,21 +660,25 @@ void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid, _eventgroup, _event, subscription_state_e::IS_SUBSCRIBING); #endif auto self = shared_from_this(); - host_->on_subscription(_service, _instance, _eventgroup, _client, _uid, _gid, true, - [this, self, _client, _uid, _gid, _service, _instance, _eventgroup, - _event, _major] + host_->on_subscription(_service, _instance, _eventgroup, _client, + _sec_client, get_env(_client), true, + [this, self, _client, _sec_client, _service, _instance, _eventgroup, + _major, _event, _filter] (const bool _subscription_accepted) { (void) ep_mgr_->find_or_create_local(_client); if (!_subscription_accepted) { - stub_->send_subscribe_nack(_client, _service, _instance, _eventgroup, _event); + if (stub_) + stub_->send_subscribe_nack(_client, _service, _instance, _eventgroup, _event); VSOMEIP_INFO << "Subscription request from client: 0x" << std::hex << _client << std::dec << " for eventgroup: 0x" << _eventgroup << " rejected from application handler."; return; - } else { + } else if (stub_) { stub_->send_subscribe_ack(_client, _service, _instance, _eventgroup, _event); } - routing_manager_base::subscribe(_client, _uid, _gid, _service, _instance, _eventgroup, _major, _event); + routing_manager_base::subscribe(_client, _sec_client, + _service, _instance, _eventgroup, _major, + _event, _filter); #ifdef VSOMEIP_ENABLE_COMPAT send_pending_notify_ones(_service, _instance, _eventgroup, _client); routing_manager_base::erase_incoming_subscription_state(_client, _service, _instance, @@ -631,7 +695,7 @@ void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid, // handle_subscription_state. std::unique_lock its_critical(remote_subscription_state_mutex_); bool inserted = insert_subscription(_service, _instance, _eventgroup, - _event, _client, &its_already_subscribed_events); + _event, _filter, _client, &its_already_subscribed_events); const bool subscriber_is_rm_host = (get_client() == _client); if (inserted) { if (0 == its_local_client) { @@ -654,17 +718,20 @@ void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid, } } else { its_critical.unlock(); - if (is_available(_service, _instance, _major)) { + if (is_available(_service, _instance, _major) && stub_) { stub_->send_subscribe(ep_mgr_->find_local(_service, _instance), - _client, _service, _instance, _eventgroup, _major, _event, - PENDING_SUBSCRIPTION_ID); + _client, _service, _instance, _eventgroup, _major, + _event, _filter, PENDING_SUBSCRIPTION_ID); } } } if (subscriber_is_rm_host) { std::lock_guard ist_lock(pending_subscription_mutex_); subscription_data_t subscription = { - _service, _instance, _eventgroup, _major, _event, _uid, _gid + _service, _instance, + _eventgroup, _major, + _event, _filter, + *_sec_client }; pending_subscriptions_.insert(subscription); } @@ -674,8 +741,10 @@ void routing_manager_impl::subscribe(client_t _client, uid_t _uid, gid_t _gid, } } -void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { +void routing_manager_impl::unsubscribe( + client_t _client, const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + event_t _event) { VSOMEIP_INFO << "UNSUBSCRIBE(" << std::hex << std::setw(4) << std::setfill('0') << _client << "): [" @@ -702,7 +771,8 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, } if (discovery_) { - host_->on_subscription(_service, _instance, _eventgroup, _client, _uid, _gid, false, + host_->on_subscription(_service, _instance, _eventgroup, _client, + _sec_client, get_env(_client), false, [](const bool _subscription_accepted){ (void)_subscription_accepted; }); if (0 == find_local_client(_service, _instance)) { if (get_client() == _client) { @@ -728,10 +798,11 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, if (get_client() == _client) { std::lock_guard ist_lock(pending_subscription_mutex_); remove_pending_subscription(_service, _instance, _eventgroup, _event); - stub_->send_unsubscribe( - ep_mgr_->find_local(_service, _instance), - _client, _service, _instance, _eventgroup, _event, - PENDING_SUBSCRIPTION_ID); + if (stub_) + stub_->send_unsubscribe( + ep_mgr_->find_local(_service, _instance), + _client, _service, _instance, _eventgroup, _event, + PENDING_SUBSCRIPTION_ID); } } ep_mgr_impl_->clear_multicast_endpoints(_service, _instance); @@ -742,15 +813,16 @@ void routing_manager_impl::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, } bool routing_manager_impl::send(client_t _client, - std::shared_ptr _message) { - return routing_manager_base::send(_client, _message); + std::shared_ptr _message, bool _force) { + + return routing_manager_base::send(_client, _message, _force); } bool routing_manager_impl::send(client_t _client, const byte_t *_data, length_t _size, instance_t _instance, bool _reliable, - client_t _bound_client, - credentials_t _credentials, - uint8_t _status_check, bool _sent_from_remote) { + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + uint8_t _status_check, bool _sent_from_remote, bool _force) { + bool is_sent(false); if (_size > VSOMEIP_MESSAGE_TYPE_POS) { std::shared_ptr its_target; @@ -775,15 +847,14 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, } else if (is_notification && _client && !is_service_discovery) { // Selective notifications! if (_client == get_client()) { #ifdef USE_DLT - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(its_target, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); #endif - deliver_message(_data, _size, _instance, _reliable, _bound_client, _credentials, _status_check, _sent_from_remote); + deliver_message(_data, _size, _instance, _reliable, + _bound_client, _sec_client, + _status_check, _sent_from_remote); return true; } its_target = find_local(_client); @@ -794,16 +865,15 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, if ((is_request && its_client == get_client()) || (is_response && find_local_client(its_service, _instance) == get_client()) || (is_notification && find_local_client(its_service, _instance) == VSOMEIP_ROUTING_CLIENT)) { - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); trace::header its_header; if (its_header.prepare(its_target, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); } #endif - is_sent = send_local(its_target, get_client(), _data, _size, _instance, _reliable, VSOMEIP_SEND, _status_check); + is_sent = send_local(its_target, get_client(), _data, _size, _instance, + _reliable, protocol::id_e::SEND_ID, _status_check); } else { // Check whether hosting application should get the message // If not, check routes to external @@ -811,7 +881,8 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, || (find_local_client(its_service, _instance) == host_->get_client() && is_request)) { // TODO: Find out how to handle session id here - is_sent = deliver_message(_data, _size, _instance, _reliable, VSOMEIP_ROUTING_CLIENT, _credentials, _status_check); + is_sent = deliver_message(_data, _size, _instance, _reliable, + VSOMEIP_ROUTING_CLIENT, _sec_client, _status_check); } else { e2e_buffer its_buffer; @@ -844,13 +915,10 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, its_service, _instance, _reliable); if (its_target) { #ifdef USE_DLT - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(its_target, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); #endif is_sent = its_target->send(_data, _size); } else { @@ -868,7 +936,8 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, std::shared_ptr its_info(find_service(its_service, _instance)); if (its_info || is_service_discovery) { if (is_notification && !is_service_discovery) { - send_local_notification(get_client(), _data, _size, _instance, _reliable, _status_check); + (void)send_local_notification(get_client(), _data, _size, _instance, + _reliable, _status_check, _force); method_t its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); std::shared_ptr its_event = find_event(its_service, _instance, its_method); @@ -930,13 +999,10 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, } #ifdef USE_DLT if (has_sent) { - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(nullptr, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); } #endif } @@ -962,13 +1028,10 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, (sd_info_ ? sd_info_->get_endpoint(false) : nullptr) : its_info->get_endpoint(_reliable); if (its_target) { #ifdef USE_DLT - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(its_target, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); #endif is_sent = its_target->send(_data, _size); } else { @@ -1009,6 +1072,7 @@ bool routing_manager_impl::send_to( const client_t _client, const std::shared_ptr &_target, std::shared_ptr _message) { + bool is_sent(false); std::shared_ptr its_serializer(get_serializer()); @@ -1050,19 +1114,17 @@ bool routing_manager_impl::send_to( bool routing_manager_impl::send_to( const std::shared_ptr &_target, const byte_t *_data, uint32_t _size, instance_t _instance) { + std::shared_ptr its_endpoint = ep_mgr_impl_->find_server_endpoint( _target->get_remote_port(), _target->is_reliable()); if (its_endpoint) { #ifdef USE_DLT - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(its_endpoint, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); #else (void) _instance; #endif @@ -1081,13 +1143,10 @@ bool routing_manager_impl::send_via_sd( if (its_endpoint) { #ifdef USE_DLT if (tc_->is_sd_enabled()) { - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(its_endpoint, true, 0x0)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); } #endif @@ -1136,13 +1195,15 @@ void routing_manager_impl::register_shadow_event(client_t _client, service_t _service, instance_t _instance, event_t _notifier, const std::set &_eventgroups, event_type_e _type, - reliability_type_e _reliability, bool _is_provided) { + reliability_type_e _reliability, bool _is_provided, bool _is_cyclic) { + routing_manager_base::register_event(_client, _service, _instance, _notifier, _eventgroups, _type, _reliability, - std::chrono::milliseconds::zero(), false, true, - nullptr, + (_is_cyclic ? std::chrono::milliseconds(1) + : std::chrono::milliseconds::zero()), + false, true, nullptr, _is_provided, true); } @@ -1172,7 +1233,7 @@ void routing_manager_impl::notify_one(service_t _service, instance_t _instance, if (its_event) { std::set > its_targets; const auto its_reliability = its_event->get_reliability(); - for (const auto& g : its_event->get_eventgroups()) { + for (const auto g : its_event->get_eventgroups()) { const auto its_eventgroup = find_eventgroup(_service, _instance, g); if (its_eventgroup) { const auto its_subscriptions = its_eventgroup->get_remote_subscriptions(); @@ -1197,7 +1258,7 @@ void routing_manager_impl::notify_one(service_t _service, instance_t _instance, if (its_targets.size() > 0) { for (const auto &its_target : its_targets) { - its_event->set_payload(_payload, _client, its_target, _force); + its_event->set_payload(_payload, _client, its_target); } } } else { @@ -1209,11 +1270,11 @@ void routing_manager_impl::notify_one(service_t _service, instance_t _instance, } void routing_manager_impl::on_availability(service_t _service, instance_t _instance, - bool _is_available, major_version_t _major, minor_version_t _minor) { + availability_state_e _state, major_version_t _major, minor_version_t _minor) { // insert subscriptions of routing manager into service discovery // to send SubscribeEventgroup after StopOffer / Offer was received - if (_is_available) { + if (_state == availability_state_e::AS_AVAILABLE) { if (discovery_) { const client_t its_local_client = find_local_client(_service, _instance); // remote service @@ -1241,7 +1302,7 @@ void routing_manager_impl::on_availability(service_t _service, instance_t _insta } } } - host_->on_availability(_service, _instance, _is_available, _major, _minor); + host_->on_availability(_service, _instance, _state, _major, _minor); } @@ -1273,7 +1334,7 @@ bool routing_manager_impl::offer_service_remotely(service_t _service, << "]"; ret = false; } else { - if (!stub_->send_provided_event_resend_request(its_offering_client, + if (stub_ && !stub_->send_provided_event_resend_request(its_offering_client, pending_remote_offer_add(_service, _instance))) { VSOMEIP_ERROR << __func__ << ": Couldn't send event resend" << "request to client 0x" << std::hex << std::setw(4) @@ -1332,7 +1393,7 @@ bool routing_manager_impl::stop_offer_service_remotely(service_t _service, clear_remote_subscriber(_service, _instance); if (discovery_ && its_info) { - discovery_->stop_offer_service(its_info); + discovery_->stop_offer_service(its_info, true); its_info->set_endpoint(std::shared_ptr(), _reliable); } } else { @@ -1344,7 +1405,7 @@ bool routing_manager_impl::stop_offer_service_remotely(service_t _service, // ensure to not send StopOffer for endpoint on which the service is // still offered its_copied_info->set_endpoint(std::shared_ptr(), !_reliable); - discovery_->stop_offer_service(its_copied_info); + discovery_->stop_offer_service(its_copied_info, true); } } @@ -1353,8 +1414,8 @@ bool routing_manager_impl::stop_offer_service_remotely(service_t _service, } void routing_manager_impl::on_message(const byte_t *_data, length_t _size, - endpoint *_receiver, const boost::asio::ip::address &_destination, - client_t _bound_client, credentials_t _credentials, + endpoint *_receiver, bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port) { #if 0 @@ -1369,10 +1430,12 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, method_t its_method; uint8_t its_check_status = e2e::profile_interface::generic_check_status::E2E_OK; instance_t its_instance(0x0); + message_type_e its_message_type; #ifdef USE_DLT bool is_forwarded(true); #endif if (_size >= VSOMEIP_SOMEIP_HEADER_SIZE) { + its_message_type = static_cast(_data[VSOMEIP_MESSAGE_TYPE_POS]); its_service = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); if (its_service == VSOMEIP_SD_SERVICE) { @@ -1381,7 +1444,11 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, if (discovery_ && its_method == sd::method) { if (configuration_->get_sd_port() == _remote_port) { if (!_remote_address.is_unspecified()) { - discovery_->on_message(_data, _size, _remote_address, _destination); + // ACL check SD message + if(!is_acl_message_allowed(_receiver, its_service, ANY_INSTANCE, _remote_address)) { + return; + } + discovery_->on_message(_data, _size, _remote_address, _is_multicast); } else { VSOMEIP_ERROR << "Ignored SD message from unknown address."; } @@ -1391,7 +1458,7 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, } } } else { - if(_destination.is_multicast()) { + if (_is_multicast) { its_instance = ep_mgr_impl_->find_instance_multicast(its_service, _remote_address); } else { its_instance = ep_mgr_impl_->find_instance(its_service, _receiver); @@ -1417,7 +1484,7 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, } //Ignore messages with invalid message type if(_size >= VSOMEIP_MESSAGE_TYPE_POS) { - if(!utility::is_valid_message_type(static_cast(_data[VSOMEIP_MESSAGE_TYPE_POS]))) { + if(!utility::is_valid_message_type(its_message_type)) { VSOMEIP_ERROR << "Ignored SomeIP message with invalid message type."; return; } @@ -1436,7 +1503,7 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, } // Security checks if enabled! - if (security::get()->is_enabled()) { + if (configuration_->is_security_enabled()) { if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { client_t requester = VSOMEIP_BYTES_TO_WORD( _data[VSOMEIP_CLIENT_POS_MIN], @@ -1456,7 +1523,7 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, << " which is already used locally ~> Skip message!"; return; } - if (!security::get()->is_remote_client_allowed()) { + if (!configuration_->is_remote_access_allowed()) { // check if policy allows remote requests. VSOMEIP_WARNING << "routing_manager_impl::on_message: " << std::hex << "Security: Remote client with client ID 0x" << requester @@ -1485,19 +1552,22 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, } #endif } + + // ACL check message + if(!is_acl_message_allowed(_receiver, its_service, its_instance, _remote_address)) { + return; + } + // Common way of message handling #ifdef USE_DLT is_forwarded = #endif on_message(its_service, its_instance, _data, _size, _receiver->is_reliable(), - _bound_client, _credentials, its_check_status, true); + _bound_client, _sec_client, its_check_status, true); } } #ifdef USE_DLT if (is_forwarded) { - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; const boost::asio::ip::address_v4 its_remote_address = _remote_address.is_v4() ? _remote_address.to_v4() : @@ -1508,19 +1578,16 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, trace::protocol_e::udp; its_header.prepare(its_remote_address, _remote_port, its_protocol, false, its_instance); - tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, _data, - its_data_size); + tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, + _data, _size); } #endif } -bool routing_manager_impl::on_message( - service_t _service, instance_t _instance, - const byte_t *_data, length_t _size, - bool _reliable, client_t _bound_client, - credentials_t _credentials, - uint8_t _check_status, - bool _is_from_remote) { +bool routing_manager_impl::on_message(service_t _service, instance_t _instance, + const byte_t *_data, length_t _size, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, + uint8_t _check_status, bool _is_from_remote) { #if 0 std::stringstream msg; msg << "rmi::on_message(" @@ -1541,15 +1608,29 @@ bool routing_manager_impl::on_message( _data[VSOMEIP_CLIENT_POS_MAX]); } +#if 0 + // ACL message check for local test purpouse + std::shared_ptr its_info = find_service(_service, _instance); + if (its_info) { + std::shared_ptr _receiver = its_info->get_endpoint(_reliable); + if (_receiver && _receiver.get()) { + if(!is_acl_message_allowed(_receiver.get(), _service, _instance, + boost::asio::ip::address_v4::from_string("127.0.0.1"))) { + return false; + } + } + } +#endif + if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) { is_forwarded = deliver_notification(_service, _instance, _data, _size, - _reliable, _bound_client, _credentials, _check_status, _is_from_remote); + _reliable, _bound_client, _sec_client, _check_status, _is_from_remote); } else if (its_client == host_->get_client()) { deliver_message(_data, _size, _instance, - _reliable, _bound_client, _credentials, _check_status, _is_from_remote); + _reliable, _bound_client, _sec_client, _check_status, _is_from_remote); } else { send(its_client, _data, _size, _instance, _reliable, - _bound_client, _credentials, _check_status, _is_from_remote); //send to proxy + _bound_client, _sec_client, _check_status, _is_from_remote, false); //send to proxy } return is_forwarded; } @@ -1689,7 +1770,7 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se if (discovery_) { if (its_info->get_major() == _major && its_info->get_minor() == _minor) { - discovery_->stop_offer_service(its_info); + discovery_->stop_offer_service(its_info, true); } } del_routing_info(_service, _instance, (its_reliable_endpoint != nullptr), @@ -1782,11 +1863,11 @@ void routing_manager_impl::on_stop_offer_service(client_t _client, service_t _se } bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, - instance_t _instance, bool _reliable, client_t _bound_client, credentials_t _credentials, + instance_t _instance, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, uint8_t _status_check, bool _is_from_remote) { + bool is_delivered(false); - std::uint32_t its_sender_uid = std::get<0>(_credentials); - std::uint32_t its_sender_gid = std::get<1>(_credentials); auto its_deserializer = get_deserializer(); its_deserializer->set_data(_data, _size); @@ -1798,8 +1879,9 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, its_message->set_instance(_instance); its_message->set_reliable(_reliable); its_message->set_check_result(_status_check); - its_message->set_uid(std::get<0>(_credentials)); - its_message->set_gid(std::get<1>(_credentials)); + if (_sec_client) + its_message->set_sec_client(*_sec_client); + its_message->set_env(get_env(_bound_client)); if (!_is_from_remote) { if (utility::is_notification(its_message->get_message_type())) { @@ -1814,9 +1896,9 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, << " ~> Skip message!"; return false; } else { - if (!security::get()->is_client_allowed(own_uid_, own_gid_, - get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message: " << " isn't allowed to receive a notification from service/instance/event " @@ -1828,7 +1910,8 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, } } } else if (utility::is_request(its_message->get_message_type())) { - if (security::get()->is_enabled() + if (configuration_->is_security_enabled() + && configuration_->is_local_routing() && its_message->get_client() != _bound_client) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message:" @@ -1841,9 +1924,9 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, return false; } - if (!security::get()->is_client_allowed(its_sender_uid, its_sender_gid, - its_message->get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(_sec_client, + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message: " << " isn't allowed to send a request to service/instance/method " @@ -1864,9 +1947,9 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, << " ~> Skip message!"; return false; } else { - if (!security::get()->is_client_allowed(own_uid_, own_gid_, - get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message: " << " isn't allowed to receive a response from service/instance/method " @@ -1879,7 +1962,7 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, } } } else { - if (!security::get()->is_remote_client_allowed()) { + if (!configuration_->is_remote_access_allowed()) { // if the message is from remote, check if // policy allows remote requests. VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() @@ -1892,9 +1975,9 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, << " ~> Skip message!"; return false; } else if (utility::is_notification(its_message->get_message_type())) { - if (!security::get()->is_client_allowed(own_uid_, own_gid_, - get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member(get_sec_client(), + its_message->get_service(), its_message->get_instance(), + its_message->get_method())) { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_impl::deliver_message: " << " isn't allowed to receive a notification from service/instance/event " @@ -1918,10 +2001,10 @@ bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, bool routing_manager_impl::deliver_notification( service_t _service, instance_t _instance, - const byte_t *_data, length_t _length, - bool _reliable, client_t _bound_client, - credentials_t _credentials, + const byte_t *_data, length_t _length, bool _reliable, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, uint8_t _status_check, bool _is_from_remote) { + event_t its_event_id = VSOMEIP_BYTES_TO_WORD( _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]); client_t its_client_id = VSOMEIP_BYTES_TO_WORD( @@ -1934,7 +2017,7 @@ bool routing_manager_impl::deliver_notification( // no subscribers for this specific event / check subscriptions // to other events of the event's eventgroups bool cache_event = false; - for (const auto& eg : its_event->get_eventgroups()) { + for (const auto eg : its_event->get_eventgroups()) { std::shared_ptr egi = find_eventgroup(_service, _instance, eg); if (egi) { for (const auto &e : egi->get_events()) { @@ -1957,37 +2040,30 @@ bool routing_manager_impl::deliver_notification( return true; // as there is nothing to do } } - const uint32_t its_length(utility::get_payload_size(_data, _length)); - if (its_length != _length - VSOMEIP_FULL_HEADER_SIZE) { - VSOMEIP_ERROR << "Message length mismatch, dropping message!"; - return false; - } - std::shared_ptr its_payload - = runtime::get()->create_payload(&_data[VSOMEIP_PAYLOAD_POS], - its_length); - if (!its_event->set_payload_dont_notify(its_payload)) { - // do not forward the notification as it was filtered - return false; - } } + auto its_length = utility::get_payload_size(_data, _length); + auto its_payload = runtime::get()->create_payload( + &_data[VSOMEIP_PAYLOAD_POS], its_length); + // incoming events statistics (void) insert_event_statistics( - _service, - _instance, - its_event_id, - utility::get_payload_size(_data, _length)); + _service, _instance, its_event_id, its_length); + // Ignore the filter for messages coming from other local clients + // as the filter was already applied there. + auto its_subscribers + = its_event->update_and_get_filtered_subscribers(its_payload, _is_from_remote); if (its_event->get_type() != event_type_e::ET_SELECTIVE_EVENT) { - for (const auto& its_local_client : its_event->get_subscribers()) { + for (const auto its_local_client : its_subscribers) { if (its_local_client == host_->get_client()) { deliver_message(_data, _length, _instance, _reliable, - _bound_client, _credentials, _status_check, _is_from_remote); + _bound_client, _sec_client, _status_check, _is_from_remote); } else { std::shared_ptr its_local_target = find_local(its_local_client); if (its_local_target) { send_local(its_local_target, VSOMEIP_ROUTING_CLIENT, - _data, _length, _instance, _reliable, VSOMEIP_SEND, _status_check); + _data, _length, _instance, _reliable, protocol::id_e::SEND_ID, _status_check); } } } @@ -1998,20 +2074,20 @@ bool routing_manager_impl::deliver_notification( if (its_client_id == VSOMEIP_ROUTING_CLIENT) its_client_id = get_client(); - auto its_subscribers = its_event->get_subscribers(); if (its_subscribers.find(its_client_id) != its_subscribers.end()) { if (its_client_id == host_->get_client()) { deliver_message(_data, _length, _instance, _reliable, - _bound_client, _credentials, _status_check, _is_from_remote); + _bound_client, _sec_client, _status_check, _is_from_remote); } else { std::shared_ptr its_local_target = find_local(its_client_id); if (its_local_target) { send_local(its_local_target, VSOMEIP_ROUTING_CLIENT, - _data, _length, _instance, _reliable, VSOMEIP_SEND, _status_check); + _data, _length, _instance, _reliable, protocol::id_e::SEND_ID, _status_check); } } } } + } else { VSOMEIP_WARNING << __func__ << ": Event [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." @@ -2048,10 +2124,10 @@ std::shared_ptr routing_manager_impl::create_service_discovery_endpoin its_service_endpoint->add_default_target(VSOMEIP_SD_SERVICE, _address, _port); if (!_reliable) { - auto its_udp_server_endpoint_impl = std::dynamic_pointer_cast< + auto its_server_endpoint = std::dynamic_pointer_cast< udp_server_endpoint_impl>(its_service_endpoint); - if (its_udp_server_endpoint_impl) - its_udp_server_endpoint_impl->join(_address); + if (its_server_endpoint) + its_server_endpoint->join(_address); } } else { VSOMEIP_ERROR<< "Service Discovery endpoint could not be created. " @@ -2102,6 +2178,37 @@ routing_manager_impl::get_offered_service_instances(service_t _service) const { return its_instances; } +bool routing_manager_impl::is_acl_message_allowed(endpoint *_receiver, + service_t _service, instance_t _instance, + const boost::asio::ip::address &_remote_address) const { + if (message_acceptance_handler_ && _receiver) { + // Check the ACL whitelist rules if shall accepts the message + + message_acceptance_t message_acceptance { +#if VSOMEIP_BOOST_VERSION < 106600 + static_cast(_remote_address.to_v4().to_ulong()), _receiver->get_local_port(), +#else + _remote_address.to_v4().to_uint(), _receiver->get_local_port(), +#endif + _receiver->is_local(), _service, _instance + }; + if (!message_acceptance_handler_(message_acceptance)) { + VSOMEIP_WARNING << "Message from " << _remote_address.to_string() + << std::hex << " with service/instance " << _instance << "/" + << _instance << " was rejected by the ACL check."; + return false; + } +#if 0 + else { + VSOMEIP_INFO << "Message from " << _remote_address.to_string() + << std::hex << " with service/instance " << _instance << "/" + << _instance << " was accepted by the ACL check."; + } +#endif + } + return true; +} + /////////////////////////////////////////////////////////////////////////////// // PRIVATE /////////////////////////////////////////////////////////////////////////////// @@ -2166,20 +2273,7 @@ void routing_manager_impl::remove_local(client_t _client, bool _remove_uid) { } routing_manager_base::remove_local(_client, clients_subscriptions, _remove_uid); - std::forward_list> services_to_release_; - { - std::lock_guard its_lock(requested_services_mutex_); - auto its_client = requested_services_.find(_client); - if (its_client != requested_services_.end()) { - for (const auto& its_service : its_client->second) { - for (const auto& its_instance : its_service.second) { - services_to_release_.push_front( - { its_service.first, its_instance.first }); - } - } - } - } - for (const auto &s : services_to_release_) { + for (const auto &s : get_requested_services(_client)) { release_service(_client, s.first, s.second); } } @@ -2210,7 +2304,7 @@ void routing_manager_impl::add_routing_info( std::lock_guard its_lock(routing_state_mutex_); if (routing_state_ == routing_state_e::RS_SUSPENDED) { - VSOMEIP_INFO << "rmi::" << __func__ << " We are suspened --> do nothing."; + VSOMEIP_INFO << "rmi::" << __func__ << " We are suspended --> do nothing."; return; } @@ -2280,89 +2374,63 @@ void routing_manager_impl::add_routing_info( { bool connected(false); std::lock_guard its_lock(requested_services_mutex_); - for(const auto &client_id : requested_services_) { - auto found_service = client_id.second.find(_service); - if (found_service != client_id.second.end()) { - auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - for (const auto &major_minor_pair : found_instance->second) { - if ((major_minor_pair.first == _major - || _major == DEFAULT_MAJOR - || major_minor_pair.first == ANY_MAJOR) - && (major_minor_pair.second <= _minor - || _minor == DEFAULT_MINOR - || major_minor_pair.second == ANY_MINOR)) { - // SWS_SD_00376 establish TCP connection to service - // service is marked as available later in on_connect() - if(!connected) { - if (udp_inserted) { - // atomically create reliable and unreliable endpoint - ep_mgr_impl_->find_or_create_remote_client( - _service, _instance); - } else { - ep_mgr_impl_->find_or_create_remote_client( - _service, _instance, true); - } - connected = true; - } - its_info->add_client(client_id.first); - break; - } - } + for (const client_t its_client : get_requesters_unlocked( + _service, _instance, _major, _minor)) { + // SWS_SD_00376 establish TCP connection to service + // service is marked as available later in on_connect() + if (!connected) { + if (udp_inserted) { + // atomically create reliable and unreliable endpoint + ep_mgr_impl_->find_or_create_remote_client( + _service, _instance); + } else { + ep_mgr_impl_->find_or_create_remote_client( + _service, _instance, true); } + connected = true; } + its_info->add_client(its_client); } } } else if (_reliable_port != ILLEGAL_PORT && is_reliable_known) { std::lock_guard its_lock(requested_services_mutex_); - bool connected(false); - for(const auto &client_id : requested_services_) { - auto found_service = client_id.second.find(_service); - if (found_service != client_id.second.end()) { - auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - for (const auto &major_minor_pair : found_instance->second) { - if ((major_minor_pair.first == _major - || _major == DEFAULT_MAJOR - || major_minor_pair.first == ANY_MAJOR) - && (major_minor_pair.second <= _minor - || _minor == DEFAULT_MINOR - || major_minor_pair.second == ANY_MINOR)) { - std::shared_ptr ep = its_info->get_endpoint(true); - if (ep) { - if (ep->is_established() && - !stub_->contained_in_routing_info( - VSOMEIP_ROUTING_CLIENT, _service, _instance, - its_info->get_major(), - its_info->get_minor())) { - on_availability(_service, _instance, - true, its_info->get_major(), its_info->get_minor()); - stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, - _service, _instance, - its_info->get_major(), - its_info->get_minor()); - if (discovery_) { - discovery_->on_endpoint_connected( - _service, _instance, ep); - } - } - } else { - // no endpoint yet, but requested -> create one - - // SWS_SD_00376 establish TCP connection to service - // service is marked as available later in on_connect() - if (!connected) { - ep_mgr_impl_->find_or_create_remote_client( - _service, _instance, true); - connected = true; - } - its_info->add_client(client_id.first); - } - break; - } + if (has_requester_unlocked(_service, _instance, _major, _minor)) { + std::shared_ptr ep = its_info->get_endpoint(true); + if (ep) { + if (ep->is_established() && + stub_ && + !stub_->contained_in_routing_info( + VSOMEIP_ROUTING_CLIENT, _service, _instance, + its_info->get_major(), + its_info->get_minor())) { + on_availability(_service, _instance, + availability_state_e::AS_AVAILABLE, + its_info->get_major(), its_info->get_minor()); + stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, + _service, _instance, + its_info->get_major(), + its_info->get_minor()); + if (discovery_) { + discovery_->on_endpoint_connected( + _service, _instance, ep); } } + } else { + // no endpoint yet, but requested -> create one + + // SWS_SD_00376 establish TCP connection to service + // service is marked as available later in on_connect() + ep_mgr_impl_->find_or_create_remote_client( + _service, _instance, true); + for (const client_t its_client : get_requesters_unlocked( + _service, _instance, _major, _minor)) { + its_info->add_client(its_client); + } } + } else { + on_availability(_service, _instance, + availability_state_e::AS_OFFERED, + its_info->get_major(), its_info->get_minor()); } } @@ -2375,38 +2443,28 @@ void routing_manager_impl::add_routing_info( { bool connected(false); std::lock_guard its_lock(requested_services_mutex_); - for (const auto &client_id : requested_services_) { - const auto found_service = client_id.second.find(_service); - if (found_service != client_id.second.end()) { - const auto found_instance = found_service->second.find( - _instance); - if (found_instance != found_service->second.end()) { - for (const auto &major_minor_pair : found_instance->second) { - if ((major_minor_pair.first == _major - || _major == DEFAULT_MAJOR - || major_minor_pair.first == ANY_MAJOR) - && (major_minor_pair.second <= _minor - || _minor == DEFAULT_MINOR - || major_minor_pair.second - == ANY_MINOR)) { - if(!connected) { - ep_mgr_impl_->find_or_create_remote_client(_service, _instance, - false); - connected = true; - } - its_info->add_client(client_id.first); - break; - } - } - } + for (const client_t its_client : get_requesters_unlocked( + _service, _instance, _major, _minor)) { + if (!connected) { + ep_mgr_impl_->find_or_create_remote_client(_service, _instance, + false); + connected = true; } + its_info->add_client(its_client); } } } if (!is_reliable_known && !tcp_inserted) { // UDP only service can be marked as available instantly - on_availability(_service, _instance, true, _major, _minor); - stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, _major, _minor); + if (has_requester_unlocked(_service, _instance, _major, _minor)) { + on_availability(_service, _instance, + availability_state_e::AS_AVAILABLE, _major, _minor); + if (stub_) + stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, _major, _minor); + } else { + on_availability(_service, _instance, + availability_state_e::AS_OFFERED, _major, _minor); + } } if (discovery_) { std::shared_ptr ep = its_info->get_endpoint(false); @@ -2416,43 +2474,32 @@ void routing_manager_impl::add_routing_info( } } else if (_unreliable_port != ILLEGAL_PORT && is_unreliable_known) { std::lock_guard its_lock(requested_services_mutex_); - for(const auto &client_id : requested_services_) { - auto found_service = client_id.second.find(_service); - if (found_service != client_id.second.end()) { - auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - for (const auto &major_minor_pair : found_instance->second) { - if ((major_minor_pair.first == _major - || _major == DEFAULT_MAJOR - || major_minor_pair.first == ANY_MAJOR) - && (major_minor_pair.second <= _minor - || _minor == DEFAULT_MINOR - || major_minor_pair.second == ANY_MINOR)) { - if (_reliable_port == ILLEGAL_PORT && !is_reliable_known && - !stub_->contained_in_routing_info( - VSOMEIP_ROUTING_CLIENT, _service, _instance, - its_info->get_major(), - its_info->get_minor())) { - on_availability(_service, _instance, - true, its_info->get_major(), its_info->get_minor()); - stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, - _service, _instance, - its_info->get_major(), - its_info->get_minor()); - if (discovery_) { - std::shared_ptr ep = its_info->get_endpoint(false); - if (ep && ep->is_established()) { - discovery_->on_endpoint_connected( - _service, _instance, - ep); - } - } - } - break; - } + if (has_requester_unlocked(_service, _instance, _major, _minor)) { + if (_reliable_port == ILLEGAL_PORT && !is_reliable_known && + stub_ && + !stub_->contained_in_routing_info( + VSOMEIP_ROUTING_CLIENT, _service, _instance, + its_info->get_major(), + its_info->get_minor())) { + on_availability(_service, _instance, + availability_state_e::AS_AVAILABLE, + its_info->get_major(), its_info->get_minor()); + stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, + _service, _instance, + its_info->get_major(), + its_info->get_minor()); + if (discovery_) { + std::shared_ptr ep = its_info->get_endpoint(false); + if (ep && ep->is_established()) { + discovery_->on_endpoint_connected( + _service, _instance, + ep); } } } + } else { + on_availability(_service, _instance, + availability_state_e::AS_OFFERED, _major, _minor); } } } @@ -2464,10 +2511,12 @@ void routing_manager_impl::del_routing_info(service_t _service, instance_t _inst if(!its_info) return; - on_availability(_service, _instance, false, - its_info->get_major(), its_info->get_minor()); - stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, + on_availability(_service, _instance, + availability_state_e::AS_UNAVAILABLE, its_info->get_major(), its_info->get_minor()); + if (stub_) + stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, + its_info->get_major(), its_info->get_minor()); // Implicit unsubscribe std::vector> its_events; @@ -2482,7 +2531,7 @@ void routing_manager_impl::del_routing_info(service_t _service, instance_t _inst // do no longer exist and the last received payload is no // longer valid. for (auto &its_event : its_eventgroup.second->get_events()) { - const auto& its_subscribers = its_event->get_subscribers(); + const auto its_subscribers = its_event->get_subscribers(); for (const auto its_subscriber : its_subscribers) { if (its_subscriber != get_client()) { its_event->remove_subscriber( @@ -2747,24 +2796,12 @@ void routing_manager_impl::init_routing_info() { = configuration_->get_reliable_port(i.first, i.second); uint16_t its_unreliable_port = configuration_->get_unreliable_port(i.first, i.second); - major_version_t its_major - = configuration_->get_major_version(i.first, i.second); - minor_version_t its_minor - = configuration_->get_minor_version(i.first, i.second); - ttl_t its_ttl - = configuration_->get_ttl(i.first, i.second); if (its_reliable_port != ILLEGAL_PORT || its_unreliable_port != ILLEGAL_PORT) { - VSOMEIP_INFO << "Adding static remote service [" - << std::hex << std::setw(4) << std::setfill('0') - << i.first << "." << i.second - << std::dec << ":" << +its_major << "." << its_minor - << "]"; - add_routing_info(i.first, i.second, - its_major, its_minor, its_ttl, + DEFAULT_MAJOR, DEFAULT_MINOR, DEFAULT_TTL, its_address, its_reliable_port, its_address, its_unreliable_port); @@ -3009,7 +3046,7 @@ void routing_manager_impl::on_subscribe_ack(client_t _client, host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /*OK*/); } - } else { + } else if (stub_) { stub_->send_subscribe_ack(its_subscriber, _service, _instance, _eventgroup, _event); } @@ -3025,20 +3062,13 @@ std::shared_ptr routing_manager_impl::find_or_create_remote_client( void routing_manager_impl::on_subscribe_nack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, remote_subscription_id_t _id, bool _simulated) { + event_t _event, remote_subscription_id_t _id) { (void)_event; // TODO: Remove completely? auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); if (its_eventgroup) { auto its_subscription = its_eventgroup->get_remote_subscription(_id); if (its_subscription) { - if (_simulated) { - // method was called because a subscription for unoffered - // service was received. Therefore, remove the remote_subscription - // from the eventgroupinfo to ensure subsequent similar - // subscriptions are handled like a new/unknown subscription - its_eventgroup->remove_remote_subscription(_id); - } its_subscription->set_client_state(_client, remote_subscription_state_e::SUBSCRIPTION_NACKED); @@ -3167,13 +3197,10 @@ void routing_manager_impl::send_error(return_code_e _return_code, its_endpoint_def->is_reliable()); if (its_endpoint) { #ifdef USE_DLT - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - trace::header its_header; if (its_header.prepare(its_endpoint, true, _instance)) tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); + _data, _size); #else (void) _instance; #endif @@ -3233,6 +3260,14 @@ routing_manager_impl::expire_subscriptions(bool _force) { auto its_subscriptions = its_eventgroup.second->get_remote_subscriptions(); for (auto &s : its_subscriptions) { + if(!s) { + VSOMEIP_ERROR << __func__ + << ": Remote subscription is NULL for eventgroup [" + << std::hex << std::setw(4) << std::setfill('0') << its_service.first << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance.first << "." + << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup.first << "]"; + continue; + } for (auto its_client : s->get_clients()) { if (_force) { its_expired_subscriptions[s].insert(its_client); @@ -3429,13 +3464,10 @@ bool routing_manager_impl::handle_local_offer_service(client_t _client, service_ } if (!already_pinged) { // find out endpoint of previously offering application - std::shared_ptr - its_old_endpoint - = std::dynamic_pointer_cast( - find_local(its_stored_client)); + auto its_old_endpoint = find_local(its_stored_client); if (its_old_endpoint) { std::lock_guard its_lock(pending_offers_mutex_); - if(stub_->send_ping(its_stored_client)) { + if (stub_ && stub_->send_ping(its_stored_client)) { pending_offers_[_service][_instance] = std::make_tuple(_major, _minor, _client, its_stored_client); @@ -3557,10 +3589,11 @@ void routing_manager_impl::register_client_error_handler(client_t _client, } void routing_manager_impl::handle_client_error(client_t _client) { - VSOMEIP_INFO << "Client 0x" << std::hex << get_client() + VSOMEIP_INFO << "routing_manager_impl::" << __func__ << " Client 0x" << std::hex << get_client() << " handles a client error(" << std::hex << _client << ")"; if (stub_) - stub_->update_registration(_client, registration_type_e::DEREGISTER_ON_ERROR); + stub_->update_registration(_client, registration_type_e::DEREGISTER_ON_ERROR, + boost::asio::ip::address(), 0); std::forward_list> its_offers; @@ -3619,17 +3652,18 @@ std::shared_ptr routing_manager_impl::get_endpoint_manage void routing_manager_impl::send_subscribe(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, - event_t _event) { + event_t _event, const std::shared_ptr &_filter) { auto endpoint = ep_mgr_->find_local(_service, _instance); - if (endpoint) { + if (endpoint && stub_) { stub_->send_subscribe(endpoint, _client, - _service, _instance, _eventgroup, _major, _event, PENDING_SUBSCRIPTION_ID); + _service, _instance, + _eventgroup, _major, + _event, _filter, + PENDING_SUBSCRIPTION_ID); } } void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { - - // Ignore setting to the current routing state { std::lock_guard its_lock(routing_state_mutex_); if (routing_state_ == _routing_state) { @@ -3640,7 +3674,7 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { routing_state_ = _routing_state; } - if(discovery_) { + if (discovery_) { switch (_routing_state) { case routing_state_e::RS_SUSPENDED: { @@ -3656,6 +3690,7 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { // remove all remote subscriptions to remotely offered services on this node expire_subscriptions(true); + std::vector> _service_infos; // send StopOffer messages for remotely offered services on this node for (const auto &its_service : get_offered_services()) { for (const auto &its_instance : its_service.second) { @@ -3666,9 +3701,16 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { << std::hex << std::setw(4) << std::setfill('0') << its_instance.first << " still offered by " << std::hex << std::setw(4) << std::setfill('0') << its_client; } - discovery_->stop_offer_service(its_instance.second); + // collect stop offers to be sent out + if (discovery_->stop_offer_service(its_instance.second, false)) { + _service_infos.push_back(its_instance.second); + } } } + // send collected stop offers packed together in one ore multiple SD messages + discovery_->send_collected_stop_offers(_service_infos); + _service_infos.clear(); + { std::lock_guard its_lock(remote_subscription_state_mutex_); remote_subscription_state_.clear(); @@ -3746,7 +3788,7 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { for (const auto &its_instance : its_service.second) { if (host_->get_configuration()->is_someip( its_service.first, its_instance.first)) { - discovery_->stop_offer_service(its_instance.second); + discovery_->stop_offer_service(its_instance.second, true); } } } @@ -3791,7 +3833,7 @@ void routing_manager_impl::set_routing_state(routing_state_e _routing_state) { } void routing_manager_impl::on_net_interface_or_route_state_changed( - bool _is_interface, std::string _if, bool _available) { + bool _is_interface, const std::string &_if, bool _available) { std::lock_guard its_lock(pending_sd_offers_mutex_); auto log_change_message = [&_if, _available, _is_interface](bool _warning) { std::stringstream ss; @@ -3864,36 +3906,184 @@ void routing_manager_impl::start_ip_routing() { VSOMEIP_INFO << VSOMEIP_ROUTING_READY_MESSAGE; } -void routing_manager_impl::requested_service_add(client_t _client, - service_t _service, - instance_t _instance, - major_version_t _major, - minor_version_t _minor) { +void +routing_manager_impl::add_requested_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + std::lock_guard ist_lock(requested_services_mutex_); - requested_services_[_client][_service][_instance].insert({ _major, _minor }); + requested_services_[_service][_instance][_major][_minor].insert(_client); } -void routing_manager_impl::requested_service_remove(client_t _client, - service_t _service, - instance_t _instance) { +void +routing_manager_impl::remove_requested_service(client_t _client, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + std::lock_guard ist_lock(requested_services_mutex_); - auto found_client = requested_services_.find(_client); - if (found_client != requested_services_.end()) { - auto found_service = found_client->second.find(_service); - if (found_service != found_client->second.end()) { - auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - // delete all requested major/minor versions - found_service->second.erase(_instance); - if (!found_service->second.size()) { - found_client->second.erase(_service); - if (!found_client->second.size()) { - requested_services_.erase(_client); + + using minor_map_t = std::map >; + using major_map_t = std::map; + using instance_map_t = std::map; + + auto delete_client = [&_client]( + minor_map_t::iterator& _minor_iter, + const major_map_t::iterator& _parent_major_iter) { + if (_minor_iter->second.erase(_client)) { // client was requester + if (_minor_iter->second.empty()) { + // client was last requester of this minor version + _minor_iter = _parent_major_iter->second.erase(_minor_iter); + } else { // there are still other requesters of this minor version + ++_minor_iter; + } + } else { // client wasn't requester + ++_minor_iter; + } + }; + + auto handle_minor = [&_minor, &delete_client]( + major_map_t::iterator& _major_iter, + const instance_map_t::iterator& _parent_instance_iter) { + if (_minor == ANY_MINOR) { + for (auto minor_iter = _major_iter->second.begin(); + minor_iter != _major_iter->second.end(); ) { + delete_client(minor_iter, _major_iter); + } + } else { + auto found_minor = _major_iter->second.find(_minor); + if (found_minor != _major_iter->second.end()) { + delete_client(found_minor, _major_iter); + } + } + if (_major_iter->second.empty()) { + // client was last requester of this major version + _major_iter = _parent_instance_iter->second.erase(_major_iter); + } else { + ++_major_iter; + } + }; + + auto found_service = requested_services_.find(_service); + if (found_service != requested_services_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + if (_major == ANY_MAJOR) { + for (auto major_iter = found_instance->second.begin(); + major_iter != found_instance->second.end();) { + handle_minor(major_iter, found_instance); + } + } else { + auto found_major = found_instance->second.find(_major); + if (found_major != found_instance->second.end()) { + handle_minor(found_major, found_instance); + } + } + if (found_instance->second.empty()) { + // client was last requester of this instance + found_service->second.erase(found_instance); + if (found_service->second.empty()) { + // client was last requester of this service + requested_services_.erase(found_service); + } + } + } + } +} + +std::vector > +routing_manager_impl::get_requested_services(client_t _client) { + std::lock_guard ist_lock(requested_services_mutex_); + std::vector> its_requests; + for (const auto& service : requested_services_) { + for (const auto& instance : service.second) { + bool requested = false; + for (const auto& major : instance.second) { + for (const auto& minor : major.second) { + if (minor.second.find(_client) != minor.second.end()) { + requested = true; + break; + } + } + if (requested) { + break; + } + } + if (requested) { + its_requests.push_back( + std::make_pair(service.first, instance.first)); + break; + } + } + } + return (its_requests); +} + +std::set +routing_manager_impl::get_requesters(service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + + std::lock_guard ist_lock(requested_services_mutex_); + return (get_requesters_unlocked(_service, _instance, _major, _minor)); +} + +std::set +routing_manager_impl::get_requesters_unlocked( + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + + std::set its_requesters; + + auto found_service = requested_services_.find(_service); + if (found_service != requested_services_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + for (const auto& its_major : found_instance->second) { + if (its_major.first == _major || _major == DEFAULT_MAJOR + || its_major.first == ANY_MAJOR) { + for (const auto &its_minor : its_major.second) { + if (its_minor.first <= _minor + || _minor == DEFAULT_MINOR + || its_minor.first == ANY_MINOR) { + if (its_requesters.empty()) { + its_requesters = its_minor.second; + } else { + its_requesters.insert(its_minor.second.cbegin(), + its_minor.second.cend()); + } + } } } } } } + return (its_requesters); +} + +bool +routing_manager_impl::has_requester_unlocked( + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) { + + auto found_service = requested_services_.find(_service); + if (found_service != requested_services_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + for (const auto& its_major : found_instance->second) { + if (its_major.first == _major || _major == DEFAULT_MAJOR + || its_major.first == ANY_MAJOR) { + for (const auto &its_minor : its_major.second) { + if (its_minor.first <= _minor + || _minor == DEFAULT_MINOR + || its_minor.first == ANY_MINOR) { + + return (true); + } + } + } + } + } + } + return (false); } std::set @@ -3934,7 +4124,7 @@ void routing_manager_impl::clear_targets_and_pending_sub_from_eventgroups( // longer valid. for (auto &its_event : its_eventgroup.second->get_events()) { const auto its_subscribers = its_event->get_subscribers(); - for (const auto& its_subscriber : its_subscribers) { + for (const auto its_subscriber : its_subscribers) { if (its_subscriber != get_client()) { its_event->remove_subscriber( its_eventgroup.first, its_subscriber); @@ -3994,7 +4184,9 @@ void routing_manager_impl::call_sd_endpoint_connected( bool routing_manager_impl::create_placeholder_event_and_subscribe( service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, client_t _client) { + event_t _event, const std::shared_ptr &_filter, + client_t _client) { + bool is_inserted(false); // we received a event which was not yet requested/offered // create a placeholder field until someone requests/offers this event with @@ -4047,7 +4239,8 @@ bool routing_manager_impl::create_placeholder_event_and_subscribe( std::shared_ptr its_event = find_event(_service, _instance, _event); if (its_event) { - is_inserted = its_event->add_subscriber(_eventgroup, _client, false); + is_inserted = its_event->add_subscriber( + _eventgroup, _filter, _client, false); } return is_inserted; } @@ -4097,7 +4290,7 @@ void routing_manager_impl::handle_subscription_state( // Subscription already acknowledged! if (_client == get_client()) { host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /*OK*/); - } else { + } else if (stub_) { stub_->send_subscribe_ack(_client, _service, _instance, _eventgroup, _event); } } @@ -4140,11 +4333,10 @@ void routing_manager_impl::memory_log_timer_cbk( if (_error) { return; } -#ifndef _WIN32 + +#if defined(__linux__) || defined(ANDROID) static const std::uint32_t its_pagesize = static_cast(getpagesize() / 1024); -#else - static const std::uint32_t its_pagesize = 4096 / 1024; -#endif + std::FILE *its_file = std::fopen("/proc/self/statm", "r"); if (!its_file) { VSOMEIP_ERROR << "memory_log_timer_cbk: couldn't open:" @@ -4166,11 +4358,10 @@ void routing_manager_impl::memory_log_timer_cbk( << std::string(std::strerror(errno)); } std::fclose(its_file); -#ifndef _WIN32 + struct timespec cputs, monots; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cputs); clock_gettime(CLOCK_MONOTONIC, &monots); -#endif VSOMEIP_INFO << "memory usage: " << "VmSize " << std::dec << its_size * its_pagesize << " kB, " @@ -4178,12 +4369,11 @@ void routing_manager_impl::memory_log_timer_cbk( << "shared pages " << std::dec << its_sharedpages * its_pagesize << " kB, " << "text " << std::dec << its_text * its_pagesize << " kB, " << "data " << std::dec << its_data * its_pagesize << " kB " -#ifndef _WIN32 << "| monotonic time: " << std::dec << monots.tv_sec << "." << std::dec << monots.tv_nsec << " cpu time: " << std::dec << cputs.tv_sec << "." << std::dec << cputs.tv_nsec -#endif ; +#endif { std::lock_guard its_lock(memory_log_timer_mutex_); @@ -4278,8 +4468,9 @@ void routing_manager_impl::send_subscription( const remote_subscription_id_t _id) { if (host_->get_client() == _offering_client) { auto self = shared_from_this(); - for (const auto& its_client : _clients) { - host_->on_subscription(_service, _instance, _eventgroup, its_client, own_uid_, own_gid_, true, + for (const auto its_client : _clients) { + host_->on_subscription(_service, _instance, _eventgroup, its_client, + get_sec_client(), get_env(its_client), true, [this, self, _service, _instance, _eventgroup, its_client, _id] (const bool _is_accepted) { try { @@ -4288,7 +4479,7 @@ void routing_manager_impl::send_subscription( &routing_manager_stub_host::on_subscribe_nack, std::dynamic_pointer_cast(shared_from_this()), its_client, _service, _instance, - _eventgroup, ANY_EVENT, _id, false); + _eventgroup, ANY_EVENT, _id); io_.post(its_callback); } else { const auto its_callback = std::bind( @@ -4304,15 +4495,15 @@ void routing_manager_impl::send_subscription( }); } } else { // service hosted by local client - for (const auto& its_client : _clients) { - if (!stub_->send_subscribe(find_local(_offering_client), its_client, - _service, _instance, _eventgroup, _major, ANY_EVENT, _id)) { + for (const auto its_client : _clients) { + if (stub_ && !stub_->send_subscribe(find_local(_offering_client), its_client, + _service, _instance, _eventgroup, _major, ANY_EVENT, nullptr, _id)) { try { const auto its_callback = std::bind( &routing_manager_stub_host::on_subscribe_nack, std::dynamic_pointer_cast(shared_from_this()), its_client, _service, _instance, _eventgroup, - ANY_EVENT, _id, true); + ANY_EVENT, _id); io_.post(its_callback); } catch (const std::exception &e) { VSOMEIP_ERROR << __func__ << e.what(); @@ -4378,7 +4569,8 @@ void routing_manager_impl::on_resend_provided_events_response( } void routing_manager_impl::print_stub_status() const { - stub_->print_endpoint_status(); + if (stub_) + stub_->print_endpoint_status(); } void routing_manager_impl::service_endpoint_connected( @@ -4389,9 +4581,12 @@ void routing_manager_impl::service_endpoint_connected( if (!_unreliable_only) { // Mark only TCP-only and TCP+UDP services available here // UDP-only services are already marked as available in add_routing_info - on_availability(_service, _instance, true, _major, _minor); - stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, + on_availability(_service, _instance, + availability_state_e::AS_AVAILABLE, _major, _minor); + if (stub_) + stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, + _major, _minor); } std::shared_ptr its_timer = @@ -4413,9 +4608,12 @@ void routing_manager_impl::service_endpoint_disconnected( service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, const std::shared_ptr& _endpoint) { (void)_endpoint; - on_availability(_service, _instance, false, _major, _minor); - stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, + on_availability(_service, _instance, + availability_state_e::AS_UNAVAILABLE, _major, _minor); + if (stub_) + stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, + _major, _minor); VSOMEIP_WARNING << __func__ << ": lost connection to remote service: [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "]"; @@ -4432,9 +4630,9 @@ routing_manager_impl::send_unsubscription(client_t _offering_client, if (host_->get_client() == _offering_client) { auto self = shared_from_this(); - for (const auto& its_client : _removed) { - host_->on_subscription(_service, _instance, - _eventgroup, its_client, own_uid_, own_gid_, false, + for (const auto its_client : _removed) { + host_->on_subscription(_service, _instance, _eventgroup, + its_client, get_sec_client(), get_env(its_client),false, [this, self, _service, _instance, _eventgroup, its_client, _id] (const bool _is_accepted) { @@ -4452,8 +4650,8 @@ routing_manager_impl::send_unsubscription(client_t _offering_client, ); } } else { - for (const auto& its_client : _removed) { - if (!stub_->send_unsubscribe(find_local(_offering_client), its_client, + for (const auto its_client : _removed) { + if (stub_ && !stub_->send_unsubscribe(find_local(_offering_client), its_client, _service, _instance, _eventgroup, ANY_EVENT, _id)) { try { const auto its_callback = std::bind( @@ -4480,19 +4678,21 @@ routing_manager_impl::send_expired_subscription(client_t _offering_client, auto self = shared_from_this(); for (const auto its_client : _removed) { host_->on_subscription(_service, _instance, - _eventgroup, its_client, own_uid_, own_gid_, false, + _eventgroup, its_client, get_sec_client(), get_env(its_client), false, [] (const bool _subscription_accepted){ (void)_subscription_accepted; }); } } else { for (const auto its_client : _removed) { - stub_->send_expired_subscription(find_local(_offering_client), its_client, - _service, _instance, _eventgroup, ANY_EVENT, _id); + if (stub_) + stub_->send_expired_subscription(find_local(_offering_client), its_client, + _service, _instance, _eventgroup, ANY_EVENT, _id); } } } +#ifndef VSOMEIP_DISABLE_SECURITY bool routing_manager_impl::update_security_policy_configuration( uint32_t _uid, uint32_t _gid, @@ -4518,6 +4718,7 @@ routing_manager_impl::remove_security_policy_configuration( return (false); } +#endif // !VSOMEIP_DISABLE_SECURITY bool routing_manager_impl::insert_event_statistics(service_t _service, instance_t _instance, method_t _method, length_t _length) { @@ -4527,7 +4728,7 @@ bool routing_manager_impl::insert_event_statistics(service_t _service, instance_ const auto its_tuple = std::make_tuple(_service, _instance, _method); const auto its_main_s = message_statistics_.find(its_tuple); if (its_main_s != message_statistics_.end()) { - // increase counter and calculate moving avergae for payload length + // increase counter and calculate moving average for payload length its_main_s->second.avg_length_ = (its_main_s->second.avg_length_ * its_main_s->second.counter_ + _length) / (its_main_s->second.counter_ + 1); @@ -4537,10 +4738,10 @@ bool routing_manager_impl::insert_event_statistics(service_t _service, instance_ // check list for entry with least counter value uint32_t its_min_count(0xFFFFFFFF); auto its_tuple_to_discard = std::make_tuple(0xFFFF, 0xFFFF, 0xFFFF); - for (const auto &it : message_statistics_) { - if (it.second.counter_ < its_min_count) { - its_min_count = it.second.counter_; - its_tuple_to_discard = it.first; + for (const auto &s : message_statistics_) { + if (s.second.counter_ < its_min_count) { + its_min_count = s.second.counter_; + its_tuple_to_discard = s.first; } } if (its_min_count != 0xFFFF @@ -4580,7 +4781,7 @@ void routing_manager_impl::statistics_log_timer_cbk(boost::system::error_code co { std::lock_guard its_lock(message_statistics_mutex_); for (const auto &s : message_statistics_) { - if (s.second.counter_ / (its_interval / 1000) >= its_min_freq) { + if (s.second.counter_ / (its_interval / 1000) > its_min_freq) { uint16_t its_subscribed(0); std::shared_ptr its_event = find_event(std::get<0>(s.first), std::get<1>(s.first), std::get<2>(s.first)); if (its_event) { @@ -4621,9 +4822,86 @@ void routing_manager_impl::statistics_log_timer_cbk(boost::system::error_code co } } +bool +routing_manager_impl::get_guest(client_t _client, + boost::asio::ip::address &_address, port_t &_port) const { + + return (routing_manager_base::get_guest(_client, _address, _port)); +} + +void +routing_manager_impl::add_guest(client_t _client, + const boost::asio::ip::address &_address, port_t _port) { + + routing_manager_base::add_guest(_client, _address, _port); +} + +void +routing_manager_impl::remove_guest(client_t _client) { + + routing_manager_base::remove_guest(_client); +} + void routing_manager_impl::send_suspend() const { + if (stub_) + stub_->send_suspend(); +} + +void routing_manager_impl::clear_local_services() { + + std::lock_guard its_lock(local_services_mutex_); + local_services_.clear(); +} + +void routing_manager_impl::register_message_acceptance_handler( + const message_acceptance_handler_t& _handler) { + message_acceptance_handler_ = _handler; +} + +void +routing_manager_impl::remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port) { + + std::map > > >its_eventgroups; + { + std::lock_guard its_lock(eventgroups_mutex_); + its_eventgroups = eventgroups_; + } + for (const auto &its_service : its_eventgroups) { + for (const auto &its_instance : its_service.second) { + for (const auto &its_eventgroup : its_instance.second) { + const auto its_info = its_eventgroup.second; + for (auto its_subscription + : its_info->get_remote_subscriptions()) { + auto its_definition = its_subscription->get_reliable(); + if (its_definition + && its_definition->get_address() == _remote_address + && its_definition->get_port() == _remote_port + && its_definition->get_remote_port() == _local_port) { + + VSOMEIP_INFO << __func__ + << ": Removing subscription to [" + << std::hex << std::setw(4) << std::setfill('0') + << its_info->get_service() << "." + << std::hex << std::setw(4) << std::setfill('0') + << its_info->get_instance() << "." + << std::hex << std::setw(4) << std::setfill('0') + << its_info->get_eventgroup() + << "] from target " + << its_definition->get_address() << ":" + << std::dec << its_definition->get_port() + << " reliable=true"; - stub_->send_suspend(); + on_remote_unsubscribe(its_subscription); + } + } + } + } + } } } // namespace vsomeip_v3 diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp deleted file mode 100644 index 06573a5..0000000 --- a/implementation/routing/src/routing_manager_proxy.cpp +++ /dev/null @@ -1,2734 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "../include/event.hpp" -#include "../include/routing_manager_host.hpp" -#include "../include/routing_manager_proxy.hpp" -#include "../../configuration/include/configuration.hpp" -#include "../../security/include/policy.hpp" -#include "../../security/include/security_impl.hpp" - -#include "../../endpoints/include/local_client_endpoint_impl.hpp" -#include "../../endpoints/include/local_server_endpoint_impl.hpp" -#include "../../message/include/deserializer.hpp" -#include "../../message/include/message_impl.hpp" -#include "../../message/include/serializer.hpp" -#include "../../service_discovery/include/runtime.hpp" -#include "../../utility/include/byteorder.hpp" -#include "../../utility/include/utility.hpp" -#ifdef USE_DLT -#include "../../tracing/include/connector_impl.hpp" -#endif - -namespace vsomeip_v3 { - -routing_manager_proxy::routing_manager_proxy(routing_manager_host *_host, - bool _client_side_logging, - const std::set > & _client_side_logging_filter) : - routing_manager_base(_host), - is_connected_(false), - is_started_(false), - state_(inner_state_type_e::ST_DEREGISTERED), - sender_(nullptr), - receiver_(nullptr), - register_application_timer_(io_), - request_debounce_timer_ (io_), - request_debounce_timer_running_(false), - client_side_logging_(_client_side_logging), - client_side_logging_filter_(_client_side_logging_filter) -{ -} - -routing_manager_proxy::~routing_manager_proxy() { -} - -void routing_manager_proxy::init() { - routing_manager_base::init(std::make_shared(this, io_, configuration_)); - { - std::lock_guard its_lock(sender_mutex_); - sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT); - } -} - -void routing_manager_proxy::start() { - is_started_ = true; - { - std::lock_guard its_lock(sender_mutex_); - if (!sender_) { - // application has been stopped and started again - sender_ = ep_mgr_->create_local(VSOMEIP_ROUTING_CLIENT); - } - if (sender_) { - sender_->start(); - } - } -} - -void routing_manager_proxy::stop() { - std::unique_lock its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERING) { - register_application_timer_.cancel(); - } - - const std::chrono::milliseconds its_timeout(configuration_->get_shutdown_timeout()); - while (state_ == inner_state_type_e::ST_REGISTERING) { - std::cv_status status = state_condition_.wait_for(its_lock, its_timeout); - if (status == std::cv_status::timeout) { - VSOMEIP_WARNING << std::hex << client_ << " registering timeout on stop"; - break; - } - } - - if (state_ == inner_state_type_e::ST_REGISTERED) { - deregister_application(); - // Waiting de-register acknowledge to synchronize shutdown - while (state_ == inner_state_type_e::ST_REGISTERED) { - std::cv_status status = state_condition_.wait_for(its_lock, its_timeout); - if (status == std::cv_status::timeout) { - VSOMEIP_WARNING << std::hex << client_ << " couldn't deregister application - timeout"; - break; - } - } - } - is_started_ = false; - its_lock.unlock(); - - { - std::lock_guard its_lock(request_timer_mutex_); - request_debounce_timer_.cancel(); - } - - if (receiver_) { - receiver_->stop(); - } - receiver_ = nullptr; - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->stop(); - } - // delete the sender - sender_ = nullptr; - } - - for (const auto& client : ep_mgr_->get_connected_clients()) { - if (client != VSOMEIP_ROUTING_CLIENT) { - remove_local(client, true); - } - } - - std::stringstream its_client; - its_client << utility::get_base_path(configuration_) << std::hex << client_; -#ifdef _WIN32 - ::_unlink(its_client.str().c_str()); -#else - if (-1 == ::unlink(its_client.str().c_str())) { - VSOMEIP_ERROR<< "routing_manager_proxy::stop unlink failed (" - << its_client.str() << "): "<< std::strerror(errno); - } -#endif -} - -std::shared_ptr routing_manager_proxy::get_configuration() const { - return host_->get_configuration(); -} - -bool routing_manager_proxy::offer_service(client_t _client, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor) { - - if(!routing_manager_base::offer_service(_client, _service, _instance, _major, _minor)) { - VSOMEIP_WARNING << "routing_manager_proxy::offer_service," - << "routing_manager_base::offer_service returned false"; - return false; - } - { - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERED) { - send_offer_service(_client, _service, _instance, _major, _minor); - } - service_data_t offer = { _service, _instance, _major, _minor }; - pending_offers_.insert(offer); - } - return true; -} - -void routing_manager_proxy::send_offer_service(client_t _client, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor) { - (void)_client; - - byte_t its_command[VSOMEIP_OFFER_SERVICE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_OFFER_SERVICE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_OFFER_SERVICE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] = _major; - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor, - sizeof(_minor)); - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::stop_offer_service(client_t _client, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor) { - - (void)_client; - - { - // Hold the mutex to ensure no placeholder event is created inbetween. - std::lock_guard its_lock(stop_mutex_); - - routing_manager_base::stop_offer_service(_client, _service, _instance, _major, _minor); - clear_remote_subscriber_count(_service, _instance); - - // Note: The last argument does not matter here as a proxy - // does not manage endpoints to the external network. - clear_service_info(_service, _instance, false); - } - - { - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERED) { - byte_t its_command[VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_STOP_OFFER_SERVICE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] = _major; - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor, - sizeof(_minor)); - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } - } - auto it = pending_offers_.begin(); - while (it != pending_offers_.end()) { - if (it->service_ == _service - && it->instance_ == _instance) { - break; - } - it++; - } - if (it != pending_offers_.end()) pending_offers_.erase(it); - } -} - -void routing_manager_proxy::request_service(client_t _client, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor) { - routing_manager_base::request_service(_client, - _service, _instance, _major, _minor); - { - std::lock_guard its_lock(state_mutex_); - size_t request_debouncing_time = configuration_->get_request_debouncing(host_->get_name()); - service_data_t request = { _service, _instance, _major, _minor }; - if (!request_debouncing_time) { - if (state_ == inner_state_type_e::ST_REGISTERED) { - std::set requests; - requests.insert(request); - send_request_services(requests); - } - requests_.insert(request); - } else { - requests_to_debounce_.insert(request); - std::lock_guard its_lock(request_timer_mutex_); - if (!request_debounce_timer_running_) { - request_debounce_timer_running_ = true; - request_debounce_timer_.expires_from_now(std::chrono::milliseconds(request_debouncing_time)); - request_debounce_timer_.async_wait( - std::bind( - &routing_manager_proxy::request_debounce_timeout_cbk, - std::dynamic_pointer_cast(shared_from_this()), - std::placeholders::_1)); - } - } - } -} - -void routing_manager_proxy::release_service(client_t _client, - service_t _service, instance_t _instance) { - routing_manager_base::release_service(_client, _service, _instance); - { - std::lock_guard its_lock(state_mutex_); - remove_pending_subscription(_service, _instance, 0xFFFF, ANY_EVENT); - - auto it = requests_to_debounce_.begin(); - while (it != requests_to_debounce_.end()) { - if (it->service_ == _service - && it->instance_ == _instance) { - break; - } - it++; - } - if (it != requests_to_debounce_.end()) { - requests_to_debounce_.erase(it); - } else if (state_ == inner_state_type_e::ST_REGISTERED) { - send_release_service(_client, _service, _instance); - } - - { - auto it = requests_.begin(); - while (it != requests_.end()) { - if (it->service_ == _service - && it->instance_ == _instance) { - break; - } - it++; - } - if (it != requests_.end()) requests_.erase(it); - } - } -} - -void routing_manager_proxy::register_event(client_t _client, - service_t _service, instance_t _instance, - event_t _notifier, - const std::set &_eventgroups, const event_type_e _type, - reliability_type_e _reliability, - std::chrono::milliseconds _cycle, bool _change_resets_cycle, - bool _update_on_change, epsilon_change_func_t _epsilon_change_func, - bool _is_provided, bool _is_shadow, bool _is_cache_placeholder) { - (void)_is_shadow; - (void)_is_cache_placeholder; - - const event_data_t registration = { - _service, - _instance, - _notifier, - _type, - _reliability, - _is_provided, - _eventgroups - }; - bool is_first(false); - { - std::lock_guard its_lock(state_mutex_); - is_first = pending_event_registrations_.find(registration) - == pending_event_registrations_.end(); -#ifndef VSOMEIP_ENABLE_COMPAT - if (is_first) { - pending_event_registrations_.insert(registration); - } -#else - bool insert = true; - if (is_first) { - for (auto iter = pending_event_registrations_.begin(); - iter != pending_event_registrations_.end();) { - if (iter->service_ == _service - && iter->instance_ == _instance - && iter->notifier_ == _notifier - && iter->is_provided_ == _is_provided - && iter->type_ == event_type_e::ET_EVENT - && _type == event_type_e::ET_SELECTIVE_EVENT) { - iter = pending_event_registrations_.erase(iter); - iter = pending_event_registrations_.insert(registration).first; - is_first = true; - insert = false; - break; - } else { - iter++; - } - } - if (insert) { - pending_event_registrations_.insert(registration); - } - } -#endif - } - if (is_first || _is_provided) { - routing_manager_base::register_event(_client, - _service, _instance, - _notifier, - _eventgroups, _type, _reliability, - _cycle, _change_resets_cycle, _update_on_change, - _epsilon_change_func, - _is_provided); - } - { - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERED && is_first) { - send_register_event(client_, _service, _instance, - _notifier, _eventgroups, _type, _reliability, _is_provided); - } - } -} - -void routing_manager_proxy::unregister_event(client_t _client, - service_t _service, instance_t _instance, event_t _notifier, - bool _is_provided) { - - routing_manager_base::unregister_event(_client, _service, _instance, - _notifier, _is_provided); - - { - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERED) { - byte_t its_command[VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNREGISTER_EVENT; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_notifier, - sizeof(_notifier)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] - = static_cast(_is_provided); - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } - } - - for (auto iter = pending_event_registrations_.begin(); - iter != pending_event_registrations_.end(); ) { - if (iter->service_ == _service - && iter->instance_ == _instance - && iter->notifier_ == _notifier - && iter->is_provided_ == _is_provided) { - pending_event_registrations_.erase(iter); - break; - } else { - iter++; - } - } - } -} - -bool routing_manager_proxy::is_field(service_t _service, instance_t _instance, - event_t _event) const { - auto event = find_event(_service, _instance, _event); - if (event && event->is_field()) { - return true; - } - return false; -} - -void routing_manager_proxy::subscribe(client_t _client, uid_t _uid, gid_t _gid, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, - event_t _event) { - (void)_uid; - (void)_gid; - { - credentials_t its_credentials = std::make_pair(own_uid_, own_gid_); - if (_event == ANY_EVENT) { - if (!is_subscribe_to_any_event_allowed(its_credentials, _client, _service, _instance, _eventgroup)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client - << " : routing_manager_proxy::subscribe: " - << " isn't allowed to subscribe to service/instance/event " - << _service << "/" << _instance << "/ANY_EVENT" - << " which violates the security policy ~> Skip subscribe!"; - return; - } - } else { - auto its_security = security_impl::get(); - if (!its_security) - return; - if (!its_security->is_client_allowed(own_uid_, own_gid_, - _client, _service, _instance, _event)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << _client - << " : routing_manager_proxy::subscribe: " - << " isn't allowed to subscribe to service/instance/event " - << _service << "/" << _instance - << "/" << _event; - return; - } - } - - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERED && is_available(_service, _instance, _major)) { - send_subscribe(client_, _service, _instance, _eventgroup, _major, _event ); - } - subscription_data_t subscription = { _service, _instance, _eventgroup, _major, _event, _uid, _gid}; - pending_subscriptions_.insert(subscription); - } -} - -void routing_manager_proxy::send_subscribe(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, - event_t _event) { - (void)_client; - - byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] = _major; - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], - &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID)); - - client_t target_client = find_local_client(_service, _instance); - if (target_client != VSOMEIP_ROUTING_CLIENT) { - auto its_target = ep_mgr_->find_or_create_local(target_client); - its_target->send(its_command, sizeof(its_command)); - } else { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::send_subscribe_nack(client_t _subscriber, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, remote_subscription_id_t _id) { - byte_t its_command[VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - client_t its_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_NACK; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client, - sizeof(its_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_subscriber, - sizeof(_subscriber)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], &_id, - sizeof(_id)); - - if (_subscriber != VSOMEIP_ROUTING_CLIENT - && _id == PENDING_SUBSCRIPTION_ID) { - auto its_target = ep_mgr_->find_local(_subscriber); - if (its_target) { - its_target->send(its_command, sizeof(its_command)); - return; - } - } - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::send_subscribe_ack(client_t _subscriber, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, remote_subscription_id_t _id) { - byte_t its_command[VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - client_t its_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_ACK; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client, - sizeof(its_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_subscriber, - sizeof(_subscriber)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], &_id, - sizeof(_id)); - - if (_subscriber != VSOMEIP_ROUTING_CLIENT - && _id == PENDING_SUBSCRIPTION_ID) { - auto its_target = ep_mgr_->find_local(_subscriber); - if (its_target) { - its_target->send(its_command, sizeof(its_command)); - return; - } - } - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::unsubscribe(client_t _client, uid_t _uid, gid_t _gid, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { - (void)_client; - (void)_uid; - (void)_gid; - { - std::lock_guard its_lock(state_mutex_); - remove_pending_subscription(_service, _instance, _eventgroup, _event); - - if (state_ == inner_state_type_e::ST_REGISTERED) { - byte_t its_command[VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNSUBSCRIBE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID)); - - auto its_target = ep_mgr_->find_local(_service, _instance); - if (its_target) { - its_target->send(its_command, sizeof(its_command)); - } else { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } - } - } -} - -bool routing_manager_proxy::send(client_t _client, const byte_t *_data, - length_t _size, instance_t _instance, - bool _reliable, - client_t _bound_client, - credentials_t _credentials, - uint8_t _status_check, - bool _sent_from_remote) { - (void)_client; - (void)_bound_client; - (void)_credentials; - (void)_sent_from_remote; - bool is_sent(false); - bool has_remote_subscribers(false); - { - std::lock_guard its_lock(state_mutex_); - if (state_ != inner_state_type_e::ST_REGISTERED) { - return false; - } - } - if (client_side_logging_) { - if (_size > VSOMEIP_MESSAGE_TYPE_POS) { - service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); - if (client_side_logging_filter_.empty() - || (1 == client_side_logging_filter_.count(std::make_tuple(its_service, ANY_INSTANCE))) - || (1 == client_side_logging_filter_.count(std::make_tuple(its_service, _instance)))) { - method_t its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); - session_t its_session = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); - client_t its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - VSOMEIP_INFO << "routing_manager_proxy::send: (" - << std::hex << std::setw(4) << std::setfill('0') << client_ <<"): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_method << ":" - << std::hex << std::setw(4) << std::setfill('0') << its_session << ":" - << std::hex << std::setw(4) << std::setfill('0') << its_client << "] " - << "type=" << std::hex << static_cast(_data[VSOMEIP_MESSAGE_TYPE_POS]) - << " thread=" << std::hex << std::this_thread::get_id(); - } - } else { - VSOMEIP_ERROR << "routing_manager_proxy::send: (" - << std::hex << std::setw(4) << std::setfill('0') << client_ - <<"): message too short to log: " << std::dec << _size; - } - } - if (_size > VSOMEIP_MESSAGE_TYPE_POS) { - std::shared_ptr its_target; - if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { - // Request - service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], - _data[VSOMEIP_SERVICE_POS_MAX]); - client_t its_client = find_local_client(its_service, _instance); - if (its_client != VSOMEIP_ROUTING_CLIENT) { - if (is_client_known(its_client)) { - its_target = ep_mgr_->find_or_create_local(its_client); - } - } - } else if (!utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) { - // Response - client_t its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - if (its_client != VSOMEIP_ROUTING_CLIENT) { - if (is_client_known(its_client)) { - its_target = ep_mgr_->find_or_create_local(its_client); - } - } - } else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) && - _client == VSOMEIP_ROUTING_CLIENT) { - // notify - has_remote_subscribers = send_local_notification(get_client(), _data, _size, - _instance, _reliable, _status_check); - } else if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) && - _client != VSOMEIP_ROUTING_CLIENT) { - // notify_one - its_target = ep_mgr_->find_local(_client); - if (its_target) { -#ifdef USE_DLT - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - - trace::header its_header; - if (its_header.prepare(nullptr, true, _instance)) - tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); -#endif - return send_local(its_target, get_client(), _data, _size, - _instance, _reliable, VSOMEIP_SEND, _status_check); - } - } - // If no direct endpoint could be found - // or for notifications ~> route to routing_manager_stub -#ifdef USE_DLT - bool message_to_stub(false); -#endif - if (!its_target) { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - its_target = sender_; -#ifdef USE_DLT - message_to_stub = true; -#endif - } else { - return false; - } - } - - bool send(true); - uint8_t command = VSOMEIP_SEND; - - if (utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) { - if (_client != VSOMEIP_ROUTING_CLIENT) { - command = VSOMEIP_NOTIFY_ONE; - } else { - command = VSOMEIP_NOTIFY; - // Do we need to deliver a notification to the routing manager? - // Only for services which already have remote clients subscribed to - send = has_remote_subscribers; - } - } -#ifdef USE_DLT - else if (!message_to_stub) { - const uint16_t its_data_size - = uint16_t(_size > USHRT_MAX ? USHRT_MAX : _size); - - trace::header its_header; - if (its_header.prepare(nullptr, true, _instance)) - tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - _data, its_data_size); - } -#endif - if (send) { - is_sent = send_local(its_target, - (command == VSOMEIP_NOTIFY_ONE ? _client : get_client()), - _data, _size, _instance, _reliable, command, _status_check); - } - } - return (is_sent); -} - -bool routing_manager_proxy::send_to(const client_t _client, - const std::shared_ptr &_target, - std::shared_ptr _message) { - (void)_client; - (void)_target; - (void)_message; - return (false); -} - -bool routing_manager_proxy::send_to( - const std::shared_ptr &_target, - const byte_t *_data, uint32_t _size, instance_t _instance) { - (void)_target; - (void)_data; - (void)_size; - (void)_instance; - return (false); -} - -void routing_manager_proxy::on_connect(const std::shared_ptr& _endpoint) { - _endpoint->set_connected(true); - _endpoint->set_established(true); - { - std::lock_guard its_lock(sender_mutex_); - if (_endpoint != sender_) { - return; - } - } - is_connected_ = true; - assign_client(); -} - -void routing_manager_proxy::on_disconnect(const std::shared_ptr& _endpoint) { - - bool is_disconnected((_endpoint == sender_)); - if (is_disconnected) { - { - std::lock_guard its_lock(sender_mutex_); - is_connected_ = false; - } - - VSOMEIP_INFO << "routing_manager_proxy::on_disconnect: Client 0x" << std::hex - << get_client() << " calling host_->on_state " - << "with DEREGISTERED"; - host_->on_state(state_type_e::ST_DEREGISTERED); - } -} - -void routing_manager_proxy::on_message(const byte_t *_data, length_t _size, - endpoint *_receiver, const boost::asio::ip::address &_destination, - client_t _bound_client, - credentials_t _credentials, - const boost::asio::ip::address &_remote_address, - std::uint16_t _remote_port) { - (void)_receiver; - (void)_destination; - (void)_remote_address; - (void)_remote_port; -#if 0 - std::stringstream msg; - msg << "rmp::on_message: "; - for (length_t i = 0; i < _size; ++i) - msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - byte_t its_command; - client_t its_client; - length_t its_length; - service_t its_service; - instance_t its_instance; - eventgroup_t its_eventgroup; - event_t its_event; - major_version_t its_major; - client_t routing_host_id = configuration_->get_id(configuration_->get_routing_host()); - client_t its_subscriber; - remote_subscription_id_t its_subscription_id(PENDING_SUBSCRIPTION_ID); - std::uint32_t its_remote_subscriber_count(0); - bool is_internal_policy_update(false); - - std::uint32_t its_sender_uid = std::get<0>(_credentials); - std::uint32_t its_sender_gid = std::get<1>(_credentials); - - auto its_security = security_impl::get(); - if (!its_security) - return; - - if (_size > VSOMEIP_COMMAND_SIZE_POS_MAX) { - its_command = _data[VSOMEIP_COMMAND_TYPE_POS]; - std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS], - sizeof(its_client)); - std::memcpy(&its_length, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN], - sizeof(its_length)); - - bool message_from_routing(false); - if (its_security->is_enabled()) { - // if security is enabled, client ID of routing must be configured - // and credential passing is active. Otherwise bound client is zero by default - message_from_routing = (_bound_client == routing_host_id); - } else { - message_from_routing = (its_client == routing_host_id); - } - - if (its_security->is_enabled() && !message_from_routing && - _bound_client != its_client) { - VSOMEIP_WARNING << std::hex << "Client " << std::setw(4) << std::setfill('0') << get_client() - << " received a message with command " << (uint32_t)its_command - << " from " << std::setw(4) << std::setfill('0') - << its_client << " which doesn't match the bound client " - << std::setw(4) << std::setfill('0') << _bound_client - << " ~> skip message!"; - return; - } - - switch (its_command) { - case VSOMEIP_SEND: { - if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a SEND command with too small size -> skip!"; - break; - } - instance_t its_instance; - bool its_reliable; - uint8_t its_check_status; - std::memcpy(&its_instance,&_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN], - sizeof(instance_t)); - std::memcpy(&its_reliable, &_data[VSOMEIP_SEND_COMMAND_RELIABLE_POS], - sizeof(its_reliable)); - std::memcpy(&its_check_status, &_data[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS], - sizeof(its_check_status)); - - // reduce by size of instance, flush, reliable, client and is_valid_crc flag - const std::uint32_t its_message_size = its_length - - (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE); - - if (its_message_size != - VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3]) - + VSOMEIP_SOMEIP_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a SEND command containing message with invalid size -> skip!"; - break; - } - - auto a_deserializer = get_deserializer(); - a_deserializer->set_data(&_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS], - its_message_size); - std::shared_ptr its_message(a_deserializer->deserialize_message()); - a_deserializer->reset(); - put_deserializer(a_deserializer); - - if (its_message) { - its_message->set_instance(its_instance); - its_message->set_reliable(its_reliable); - its_message->set_check_result(its_check_status); - its_message->set_uid(std::get<0>(_credentials)); - its_message->set_gid(std::get<1>(_credentials)); - - if (!message_from_routing) { - if (utility::is_notification(its_message->get_message_type())) { - if (!is_response_allowed(_bound_client, its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " received a notification from client 0x" << _bound_client - << " which does not offer service/instance/event " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " ~> Skip message!"; - return; - } else { - if (!its_security->is_client_allowed(own_uid_, own_gid_, - get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " isn't allowed to receive a notification from service/instance/event " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " respectively from client 0x" << _bound_client - << " ~> Skip message!"; - return; - } - cache_event_payload(its_message); - } - } else if (utility::is_request(its_message->get_message_type())) { - if (its_security->is_enabled() - && its_message->get_client() != _bound_client) { - VSOMEIP_WARNING << std::hex << "vSomeIP Security: Client 0x" << std::setw(4) << std::setfill('0') << get_client() - << " received a request from client 0x" << std::setw(4) << std::setfill('0') - << its_message->get_client() << " to service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() << " which doesn't match the bound client 0x" - << std::setw(4) << std::setfill('0') << _bound_client - << " ~> skip message!"; - return; - } - - if (!its_security->is_client_allowed(its_sender_uid, its_sender_gid, - its_message->get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_message->get_client() - << " : routing_manager_proxy::on_message: " - << "isn't allowed to send a request to service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " ~> Skip message!"; - return; - } - } else { // response - if (!is_response_allowed(_bound_client, its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " received a response from client 0x" << _bound_client - << " which does not offer service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " ~> Skip message!"; - return; - } else { - if (!its_security->is_client_allowed(own_uid_, own_gid_, - get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " isn't allowed to receive a response from service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " respectively from client 0x" << _bound_client - << " ~> Skip message!"; - return; - } - } - } - } else { - if (!its_security->is_remote_client_allowed()) { - // if the message is from routing manager, check if - // policy allows remote requests. - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << std::hex << "Security: Remote clients via routing manager with client ID 0x" << its_client - << " are not allowed to communicate with service/instance/method " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " respectively with client 0x" << get_client() - << " ~> Skip message!"; - return; - } else if (utility::is_notification(its_message->get_message_type())) { - // As subscription is sent on eventgroup level, incoming remote event ID's - // need to be checked as well if remote clients are allowed - // and the local policy only allows specific events in the eventgroup to be received. - if (!its_security->is_client_allowed(own_uid_, own_gid_, - get_client(), its_message->get_service(), - its_message->get_instance(), its_message->get_method())) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " isn't allowed to receive a notification from service/instance/event " - << its_message->get_service() << "/" << its_message->get_instance() - << "/" << its_message->get_method() - << " respectively from remote clients via routing manager with client ID 0x" - << routing_host_id - << " ~> Skip message!"; - return; - } - cache_event_payload(its_message); - } - } -#ifdef USE_DLT - if (client_side_logging_ - && (client_side_logging_filter_.empty() - || (1 == client_side_logging_filter_.count(std::make_tuple(its_message->get_service(), ANY_INSTANCE))) - || (1 == client_side_logging_filter_.count(std::make_tuple(its_message->get_service(), its_message->get_instance()))))) { - trace::header its_header; - if (its_header.prepare(nullptr, false, its_instance)) - tc_->trace(its_header.data_, VSOMEIP_TRACE_HEADER_SIZE, - &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS], - static_cast(its_message_size)); - } -#endif - - host_->on_message(std::move(its_message)); - } else { - VSOMEIP_ERROR << "Routing proxy: on_message: " - << "SomeIP-Header deserialization failed!"; - } - break; - } - - case VSOMEIP_ASSIGN_CLIENT_ACK: { - if (_size != VSOMEIP_ASSIGN_CLIENT_ACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a VSOMEIP_ASSIGN_CLIENT_ACK command with wrong size ~> skip!"; - break; - } - client_t its_assigned_client(VSOMEIP_CLIENT_UNSET); - std::memcpy(&its_assigned_client, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS], sizeof(client_)); - on_client_assign_ack(its_assigned_client); - break; - } - case VSOMEIP_ROUTING_INFO: - if (_size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) { - VSOMEIP_WARNING << "Received a ROUTING_INFO command with invalid size -> skip!"; - break; - } - if (!its_security->is_enabled() || message_from_routing) { - on_routing_info(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length); - } else { - VSOMEIP_WARNING << "routing_manager_proxy::on_message: " - << std::hex << "Security: Client 0x" << get_client() - << " received an routing info from a client which isn't the routing manager" - << " : Skip message!"; - } - break; - - case VSOMEIP_PING: - if (_size != VSOMEIP_PING_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a PING command with wrong size ~> skip!"; - break; - } - send_pong(); - VSOMEIP_TRACE << "PING(" - << std::hex << std::setw(4) << std::setfill('0') << client_ << ")"; - break; - - case VSOMEIP_SUBSCRIBE: - if (_size != VSOMEIP_SUBSCRIBE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a SUBSCRIBE command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_major)); - std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7], - sizeof(its_event)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 9], - sizeof(its_subscription_id)); - { - std::unique_lock its_lock(incoming_subscriptions_mutex_); - if (its_subscription_id != PENDING_SUBSCRIPTION_ID) { - its_lock.unlock(); -#ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::set_incoming_subscription_state(its_client, its_service, - its_instance, its_eventgroup, its_event, subscription_state_e::IS_SUBSCRIBING); -#endif - // Remote subscriber: Notify routing manager initially + count subscribes - auto self = shared_from_this(); - host_->on_subscription(its_service, its_instance, its_eventgroup, - its_client, its_sender_uid, its_sender_gid, true, - [this, self, its_client, its_service, its_instance, - its_eventgroup, its_event, its_subscription_id, its_major] - (const bool _subscription_accepted){ - std::uint32_t its_count = 0; - if(_subscription_accepted) { - send_subscribe_ack(its_client, its_service, its_instance, - its_eventgroup, its_event, its_subscription_id); - std::set its_already_subscribed_events; - bool inserted = insert_subscription(its_service, its_instance, its_eventgroup, - its_event, VSOMEIP_ROUTING_CLIENT, &its_already_subscribed_events); - if (inserted) { - notify_remote_initially(its_service, its_instance, its_eventgroup, - its_already_subscribed_events); - } -#ifdef VSOMEIP_ENABLE_COMPAT - send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client, true); -#endif - its_count = get_remote_subscriber_count(its_service, its_instance, its_eventgroup, true); - } else { - send_subscribe_nack(its_client, its_service, its_instance, - its_eventgroup, its_event, its_subscription_id); - } - VSOMEIP_INFO << "SUBSCRIBE(" - << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << ":" - << std::hex << std::setw(4) << std::setfill('0') << its_event << ":" - << std::dec << (uint16_t)its_major << "] " - << (bool)(its_subscription_id != PENDING_SUBSCRIPTION_ID) << " " - << (_subscription_accepted ? std::to_string(its_count) : "-") - << (_subscription_accepted ? " ACCEPTED" : " NOT ACCEPTED"); -#ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::erase_incoming_subscription_state(its_client, its_service, - its_instance, its_eventgroup, its_event); -#endif - }); - } else if (is_client_known(its_client)) { - its_lock.unlock(); - if (!message_from_routing) { - if (its_event == ANY_EVENT) { - if (!is_subscribe_to_any_event_allowed(_credentials, its_client, its_service, its_instance, its_eventgroup)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client - << " : routing_manager_proxy::on_message: " - << " isn't allowed to subscribe to service/instance/event " - << its_service << "/" << its_instance << "/ANY_EVENT" - << " which violates the security policy ~> Skip subscribe!"; - return; - } - } else { - if (!its_security->is_client_allowed(its_sender_uid, its_sender_gid, - its_client, its_service, its_instance, its_event)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client - << " : routing_manager_proxy::on_message: " - << " subscribes to service/instance/event " - << its_service << "/" << its_instance << "/" << its_event - << " which violates the security policy ~> Skip subscribe!"; - return; - } - } - } else { - if (!its_security->is_remote_client_allowed()) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client - << " : routing_manager_proxy::on_message: " - << std::hex << "Routing manager with client ID 0x" - << its_client - << " isn't allowed to subscribe to service/instance/event " - << its_service << "/" << its_instance - << "/" << its_event - << " respectively to client 0x" << get_client() - << " ~> Skip Subscribe!"; - return; - } - } - - // Local & already known subscriber: create endpoint + send (N)ACK + insert subscription -#ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::set_incoming_subscription_state(its_client, its_service, - its_instance, its_eventgroup, its_event, subscription_state_e::IS_SUBSCRIBING); -#endif - (void) ep_mgr_->find_or_create_local(its_client); - auto self = shared_from_this(); - host_->on_subscription(its_service, its_instance, - its_eventgroup, its_client, its_sender_uid, its_sender_gid, true, - [this, self, its_client, its_sender_uid, its_sender_gid, its_service, - its_instance, its_eventgroup, its_event, its_major] - (const bool _subscription_accepted) { - if (!_subscription_accepted) { - send_subscribe_nack(its_client, its_service, its_instance, - its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID); - } else { - send_subscribe_ack(its_client, its_service, its_instance, - its_eventgroup, its_event, PENDING_SUBSCRIPTION_ID); - routing_manager_base::subscribe(its_client, its_sender_uid, its_sender_gid, - its_service, its_instance, its_eventgroup, its_major, its_event); -#ifdef VSOMEIP_ENABLE_COMPAT - send_pending_notify_ones(its_service, its_instance, its_eventgroup, its_client); -#endif - } -#ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::erase_incoming_subscription_state(its_client, its_service, - its_instance, its_eventgroup, its_event); -#endif - }); - } else { - // Local & not yet known subscriber ~> set pending until subscriber gets known! - subscription_data_t subscription = { its_service, its_instance, - its_eventgroup, its_major, its_event, its_sender_uid, its_sender_gid }; - pending_incoming_subscripitons_[its_client].insert(subscription); - } - } - if (its_subscription_id == PENDING_SUBSCRIPTION_ID) { // local subscription - VSOMEIP_INFO << "SUBSCRIBE(" - << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << ":" - << std::hex << std::setw(4) << std::setfill('0') << its_event << ":" - << std::dec << (uint16_t)its_major << "]"; - } - break; - - case VSOMEIP_UNSUBSCRIBE: - if (_size != VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received an UNSUBSCRIBE command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_event)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_subscription_id)); - host_->on_subscription(its_service, its_instance, its_eventgroup, its_client, its_sender_uid, its_sender_gid, false, [](const bool _subscription_accepted){ (void)_subscription_accepted; }); - if (its_subscription_id == PENDING_SUBSCRIPTION_ID) { - // Local subscriber: withdraw subscription - routing_manager_base::unsubscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance, its_eventgroup, its_event); - } else { - // Remote subscriber: withdraw subscription only if no more remote subscriber exists - its_remote_subscriber_count = get_remote_subscriber_count(its_service, - its_instance, its_eventgroup, false); - if (!its_remote_subscriber_count) { - routing_manager_base::unsubscribe(VSOMEIP_ROUTING_CLIENT, ANY_UID, ANY_GID, its_service, - its_instance, its_eventgroup, its_event); - } - send_unsubscribe_ack(its_service, its_instance, its_eventgroup, - its_subscription_id); - } - VSOMEIP_INFO << "UNSUBSCRIBE(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << its_event << "] " - << (bool)(its_subscription_id != PENDING_SUBSCRIPTION_ID) << " " - << std::dec << its_remote_subscriber_count; - break; - - case VSOMEIP_EXPIRED_SUBSCRIPTION: - if (_size != VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received an VSOMEIP_EXPIRED_SUBSCRIPTION command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_event)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_subscription_id)); - host_->on_subscription(its_service, its_instance, its_eventgroup, its_client, its_sender_uid, its_sender_gid, false, [](const bool _subscription_accepted){ (void)_subscription_accepted; }); - if (its_subscription_id == PENDING_SUBSCRIPTION_ID) { - // Local subscriber: withdraw subscription - routing_manager_base::unsubscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance, its_eventgroup, its_event); - } else { - // Remote subscriber: withdraw subscription only if no more remote subscriber exists - its_remote_subscriber_count = get_remote_subscriber_count(its_service, - its_instance, its_eventgroup, false); - if (!its_remote_subscriber_count) { - routing_manager_base::unsubscribe(VSOMEIP_ROUTING_CLIENT, ANY_UID, ANY_GID, its_service, - its_instance, its_eventgroup, its_event); - } - } - VSOMEIP_INFO << "UNSUBSCRIBE EXPIRED SUBSCRIPTION(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << its_event << "] " - << (bool)(its_subscription_id != PENDING_SUBSCRIPTION_ID) << " " - << std::dec << its_remote_subscriber_count; - break; - - case VSOMEIP_SUBSCRIBE_NACK: - if (_size != VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a VSOMEIP_SUBSCRIBE_NACK command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_subscriber)); - std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_event)); - - on_subscribe_nack(its_subscriber, its_service, its_instance, its_eventgroup, its_event); - VSOMEIP_INFO << "SUBSCRIBE NACK(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << its_event << "]"; - break; - - case VSOMEIP_SUBSCRIBE_ACK: - if (_size != VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a VSOMEIP_SUBSCRIBE_ACK command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_subscriber)); - std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_event)); - - on_subscribe_ack(its_subscriber, its_service, its_instance, its_eventgroup, its_event); - VSOMEIP_INFO << "SUBSCRIBE ACK(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << its_event << "]"; - break; - - case VSOMEIP_OFFERED_SERVICES_RESPONSE: - if (_size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) { - VSOMEIP_WARNING << "Received a VSOMEIP_OFFERED_SERVICES_RESPONSE command with invalid size -> skip!"; - break; - } - if (!its_security->is_enabled() || message_from_routing) { - on_offered_services_info(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length); - } else { - VSOMEIP_WARNING << std::hex << "Security: Client 0x" << get_client() - << " received an offered services info from a client which isn't the routing manager" - << " : Skip message!"; - } - break; - case VSOMEIP_RESEND_PROVIDED_EVENTS: { - if (_size != VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a RESEND_PROVIDED_EVENTS command with wrong size ~> skip!"; - break; - } - pending_remote_offer_id_t its_pending_remote_offer_id(0); - std::memcpy(&its_pending_remote_offer_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_remote_offer_id_t)); - resend_provided_event_registrations(); - send_resend_provided_event_response(its_pending_remote_offer_id); - VSOMEIP_INFO << "RESEND_PROVIDED_EVENTS(" - << std::hex << std::setw(4) << std::setfill('0') - << its_client << ")"; - break; - } - case VSOMEIP_UPDATE_SECURITY_POLICY_INT: - is_internal_policy_update = true; - /* Fallthrough */ - case VSOMEIP_UPDATE_SECURITY_POLICY: { - if (_size < VSOMEIP_COMMAND_HEADER_SIZE + sizeof(pending_security_update_id_t) || - _size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_UPDATE_SECURITY_POLICY command with wrong size -> skip!"; - break; - } - if (!its_security->is_enabled() || message_from_routing) { - pending_security_update_id_t its_update_id(0); - - std::memcpy(&its_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_security_update_id_t)); - - std::shared_ptr its_policy(std::make_shared()); - const byte_t *its_policy_data = _data + (VSOMEIP_COMMAND_PAYLOAD_POS + - sizeof(pending_security_update_id_t)); - - uint32_t its_policy_size = uint32_t(_size - (VSOMEIP_COMMAND_PAYLOAD_POS - + sizeof(pending_security_update_id_t))); - - bool is_valid = its_policy->deserialize(its_policy_data, its_policy_size); - if (is_valid) { - uint32_t its_uid; - uint32_t its_gid; - is_valid = its_policy->get_uid_gid(its_uid, its_gid); - if (is_valid) { - if (is_internal_policy_update - || its_security->is_policy_update_allowed(its_uid, its_policy)) { - its_security->update_security_policy(its_uid, its_gid, its_policy); - send_update_security_policy_response(its_update_id); - } - } else { - VSOMEIP_ERROR << "vSomeIP Security: Policy has no valid uid/gid!"; - } - } else { - VSOMEIP_ERROR << "vSomeIP Security: Policy deserialization failed!"; - } - } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " received a security policy update from a client which isn't the routing manager" - << " : Skip message!"; - } - break; - } - case VSOMEIP_REMOVE_SECURITY_POLICY: { - if (_size != VSOMEIP_REMOVE_SECURITY_POLICY_COMMAND_SIZE) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_REMOVE_SECURITY_POLICY command with wrong size ~> skip!"; - break; - } - if (!its_security->is_enabled() || message_from_routing) { - pending_security_update_id_t its_update_id(0); - uint32_t its_uid(ANY_UID); - uint32_t its_gid(ANY_GID); - - std::memcpy(&its_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_security_update_id_t)); - std::memcpy(&its_uid, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(uint32_t)); - std::memcpy(&its_gid, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(uint32_t)); - if (its_security->is_policy_removal_allowed(its_uid)) { - its_security->remove_security_policy(its_uid, its_gid); - send_remove_security_policy_response(its_update_id); - } - } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << "received a security policy removal from a client which isn't the routing manager" - << " : Skip message!"; - } - break; - } - case VSOMEIP_DISTRIBUTE_SECURITY_POLICIES: { - if (_size < VSOMEIP_COMMAND_HEADER_SIZE || - _size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_DISTRIBUTE_SECURITY_POLICIES command with wrong size -> skip!"; - break; - } - if (!its_security->is_enabled() || message_from_routing) { - uint32_t its_policy_count(0); - uint32_t its_policy_size(0); - const byte_t* buffer_ptr = 0; - - if (VSOMEIP_COMMAND_PAYLOAD_POS + sizeof(uint32_t) * 2 <= _size) { - std::memcpy(&its_policy_count, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(uint32_t)); - - // skip policy count field - buffer_ptr = _data + (VSOMEIP_COMMAND_PAYLOAD_POS + - sizeof(uint32_t)); - - for (uint32_t i = 0; i < its_policy_count; i++) { - uint32_t its_uid(0); - uint32_t its_gid(0); - std::shared_ptr its_policy(std::make_shared()); - // length field of next (UID/GID + policy) - if (buffer_ptr + sizeof(uint32_t) <= _data + _size) { - std::memcpy(&its_policy_size, buffer_ptr, - sizeof(uint32_t)); - buffer_ptr += sizeof(uint32_t); - - if (buffer_ptr + its_policy_size <= _data + _size) { - if (its_security->parse_policy(buffer_ptr, its_policy_size, its_uid, its_gid, its_policy)) { - if (its_security->is_policy_update_allowed(its_uid, its_policy)) { - its_security->update_security_policy(its_uid, its_gid, its_policy); - } - } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() << " could not parse policy!"; - } - } - } - } - } - } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << " received a security policy distribution command from a client which isn't the routing manager" - << " : Skip message!"; - } - break; - } - case VSOMEIP_UPDATE_SECURITY_CREDENTIALS: { - if (_size < VSOMEIP_COMMAND_HEADER_SIZE || - _size - VSOMEIP_COMMAND_HEADER_SIZE != its_length) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_UPDATE_SECURITY_CREDENTIALS command with wrong size -> skip!"; - break; - } - if (!its_security->is_enabled() || message_from_routing) { - on_update_security_credentials(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length); - } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_message: " - << "received a security credential update from a client which isn't the routing manager" - << " : Skip message!"; - } - break; - } - - case VSOMEIP_SUSPEND: - on_suspend(); // cleanup remote subscribers - break; - - default: - break; - } - } -} - -void routing_manager_proxy::on_routing_info(const byte_t *_data, - uint32_t _size) { -#if 0 - std::stringstream msg; - msg << "rmp::on_routing_info(" << std::hex << client_ << "): "; - for (uint32_t i = 0; i < _size; ++i) - msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - auto its_security = security_impl::get(); - if (!its_security) - return; - - uint32_t i = 0; - while (i + sizeof(uint32_t) + sizeof(routing_info_entry_e) <= _size) { - routing_info_entry_e routing_info_entry; - std::memcpy(&routing_info_entry, &_data[i], sizeof(routing_info_entry_e)); - i += uint32_t(sizeof(routing_info_entry_e)); - - uint32_t its_client_size; - std::memcpy(&its_client_size, &_data[i], sizeof(uint32_t)); - i += uint32_t(sizeof(uint32_t)); - - if (its_client_size + i > _size) { - VSOMEIP_WARNING << "Client 0x" << std::hex << get_client() << " : " - << "Processing of routing info failed due to bad length fields!"; - return; - } - - if (i + sizeof(client_t) <= _size) { - client_t its_client; - std::memcpy(&its_client, &_data[i], sizeof(client_t)); - i += uint32_t(sizeof(client_t)); - - if (routing_info_entry == routing_info_entry_e::RIE_ADD_CLIENT) { - { - std::lock_guard its_lock(known_clients_mutex_); - known_clients_.insert(its_client); - } - if (its_client == get_client()) { - VSOMEIP_INFO << std::hex << "Application/Client " << get_client() - << " (" << host_->get_name() << ") is registered."; - -#ifndef _WIN32 - if (!its_security->check_credentials(get_client(), own_uid_, own_gid_)) { - VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::on_routing_info: RIE_ADD_CLIENT: isn't allowed" - << " to use the server endpoint due to credential check failed!"; - deregister_application(); - host_->on_state(static_cast(inner_state_type_e::ST_DEREGISTERED)); - return; - } -#endif - { - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_REGISTERING) { - boost::system::error_code ec; - register_application_timer_.cancel(ec); - send_registered_ack(); - send_pending_commands(); - state_ = inner_state_type_e::ST_REGISTERED; - // Notify stop() call about clean deregistration - state_condition_.notify_one(); - } - } - - // inform host about its own registration state changes - if (state_ == inner_state_type_e::ST_REGISTERED) - host_->on_state(static_cast(inner_state_type_e::ST_REGISTERED)); - - } - } else if (routing_info_entry == routing_info_entry_e::RIE_DEL_CLIENT) { - { - std::lock_guard its_lock(known_clients_mutex_); - known_clients_.erase(its_client); - } - if (its_client == get_client()) { - its_security->remove_client_to_uid_gid_mapping(its_client); - VSOMEIP_INFO << std::hex << "Application/Client " << get_client() - << " (" << host_->get_name() << ") is deregistered."; - - // inform host about its own registration state changes - host_->on_state(static_cast(inner_state_type_e::ST_DEREGISTERED)); - - { - std::lock_guard its_lock(state_mutex_); - state_ = inner_state_type_e::ST_DEREGISTERED; - // Notify stop() call about clean deregistration - state_condition_.notify_one(); - } - } else if (its_client != VSOMEIP_ROUTING_CLIENT) { - remove_local(its_client, true); - } - } - - uint32_t j = 0; - while (j + sizeof(uint32_t) <= its_client_size) { - uint32_t its_services_size; - std::memcpy(&its_services_size, &_data[i + j], sizeof(uint32_t)); - j += uint32_t(sizeof(uint32_t)); - - if (its_services_size >= sizeof(service_t) + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)) { - its_services_size -= uint32_t(sizeof(service_t)); - - service_t its_service; - std::memcpy(&its_service, &_data[i + j], sizeof(service_t)); - j += uint32_t(sizeof(service_t)); - - while (its_services_size >= sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)) { - instance_t its_instance; - std::memcpy(&its_instance, &_data[i + j], sizeof(instance_t)); - j += uint32_t(sizeof(instance_t)); - - major_version_t its_major; - std::memcpy(&its_major, &_data[i + j], sizeof(major_version_t)); - j += uint32_t(sizeof(major_version_t)); - - minor_version_t its_minor; - std::memcpy(&its_minor, &_data[i + j], sizeof(minor_version_t)); - j += uint32_t(sizeof(minor_version_t)); - - if (routing_info_entry == routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE) { - if (get_routing_state() == routing_state_e::RS_SUSPENDED) { - VSOMEIP_INFO << "rmp::" <<__func__ << " We are in suspended mode, the service will not be added!"; - return; - } - { - std::lock_guard its_lock(known_clients_mutex_); - known_clients_.insert(its_client); - } - { - std::lock_guard its_lock(local_services_mutex_); - local_services_[its_service][its_instance] = std::make_tuple(its_major, its_minor, its_client); - } - { - std::lock_guard its_lock(state_mutex_); - send_pending_subscriptions(its_service, its_instance, its_major); - } - host_->on_availability(its_service, its_instance, true, its_major, its_minor); - VSOMEIP_INFO << "ON_AVAILABLE(" - << std::hex << std::setw(4) << std::setfill('0') << get_client() <<"): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance - << ":" << std::dec << int(its_major) << "." << std::dec << its_minor << "]"; - } else if (routing_info_entry == routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE) { - { - std::lock_guard its_lock(local_services_mutex_); - auto found_service = local_services_.find(its_service); - if (found_service != local_services_.end()) { - found_service->second.erase(its_instance); - // move previously offering client to history - local_services_history_[its_service][its_instance].insert(its_client); - if (found_service->second.size() == 0) { - local_services_.erase(its_service); - } - } - } - on_stop_offer_service(its_service, its_instance, its_major, its_minor); - host_->on_availability(its_service, its_instance, false, its_major, its_minor); - VSOMEIP_INFO << "ON_UNAVAILABLE(" - << std::hex << std::setw(4) << std::setfill('0') << get_client() <<"): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance - << ":" << std::dec << int(its_major) << "." << std::dec << its_minor << "]"; - - if (its_client == get_client()) { - VSOMEIP_INFO << __func__ - << ": Clearing subscriptions for service [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "]"; - unsubscribe_all(its_service, its_instance); - } - } - - its_services_size -= uint32_t(sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t) ); - } - } - } - - i += j; - } - } - { - struct subscription_info { - service_t service_id_; - instance_t instance_id_; - eventgroup_t eventgroup_id_; - client_t client_id_; - major_version_t major_; - event_t event_; - uid_t uid_; - gid_t gid_; - }; - std::lock_guard its_lock(incoming_subscriptions_mutex_); - std::forward_list subscription_actions; - if (pending_incoming_subscripitons_.size()) { - { - std::lock_guard its_lock(known_clients_mutex_); - for (const client_t client : known_clients_) { - auto its_client = pending_incoming_subscripitons_.find(client); - if (its_client != pending_incoming_subscripitons_.end()) { - for (const auto& subscription : its_client->second) { - subscription_actions.push_front( - { subscription.service_, subscription.instance_, - subscription.eventgroup_, client, - subscription.major_, subscription.event_, - subscription.uid_, subscription.gid_ }); - } - } - } - } - for (const subscription_info &si : subscription_actions) { -#ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::set_incoming_subscription_state(si.client_id_, si.service_id_, si.instance_id_, - si.eventgroup_id_, si.event_, subscription_state_e::IS_SUBSCRIBING); -#endif - (void) ep_mgr_->find_or_create_local(si.client_id_); - auto self = shared_from_this(); - host_->on_subscription( - si.service_id_, si.instance_id_, si.eventgroup_id_, - si.client_id_, si.uid_, si.gid_, true, - [this, self, si](const bool _subscription_accepted) { - if (!_subscription_accepted) { - send_subscribe_nack(si.client_id_, si.service_id_, - si.instance_id_, si.eventgroup_id_, si.event_, PENDING_SUBSCRIPTION_ID); - } else { - send_subscribe_ack(si.client_id_, si.service_id_, - si.instance_id_, si.eventgroup_id_, si.event_, PENDING_SUBSCRIPTION_ID); - routing_manager_base::subscribe(si.client_id_, si.uid_, si.gid_, - si.service_id_, si.instance_id_, si.eventgroup_id_, - si.major_, si.event_); -#ifdef VSOMEIP_ENABLE_COMPAT - send_pending_notify_ones(si.service_id_, - si.instance_id_, si.eventgroup_id_, si.client_id_); -#endif - } -#ifdef VSOMEIP_ENABLE_COMPAT - routing_manager_base::erase_incoming_subscription_state(si.client_id_, si.service_id_, - si.instance_id_, si.eventgroup_id_, si.event_); -#endif - { - std::lock_guard its_lock2(incoming_subscriptions_mutex_); - pending_incoming_subscripitons_.erase(si.client_id_); - } - }); - } - } - } -} - -void routing_manager_proxy::on_offered_services_info(const byte_t *_data, - uint32_t _size) { -#if 0 - std::stringstream msg; - msg << "rmp::on_offered_services_info(" << std::hex << client_ << "): "; - for (uint32_t i = 0; i < _size; ++i) - msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - - std::vector> its_offered_services_info; - - uint32_t i = 0; - while (i + sizeof(uint32_t) + sizeof(routing_info_entry_e) <= _size) { - routing_info_entry_e routing_info_entry; - std::memcpy(&routing_info_entry, &_data[i], sizeof(routing_info_entry_e)); - i += uint32_t(sizeof(routing_info_entry_e)); - - uint32_t its_service_entry_size; - std::memcpy(&its_service_entry_size, &_data[i], sizeof(uint32_t)); - i += uint32_t(sizeof(uint32_t)); - - if (its_service_entry_size + i > _size) { - VSOMEIP_WARNING << "Client 0x" << std::hex << get_client() << " : " - << "Processing of offered services info failed due to bad length fields!"; - return; - } - - if (its_service_entry_size >= sizeof(service_t) + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)) { - service_t its_service; - std::memcpy(&its_service, &_data[i], sizeof(service_t)); - i += uint32_t(sizeof(service_t)); - - instance_t its_instance; - std::memcpy(&its_instance, &_data[i], sizeof(instance_t)); - i += uint32_t(sizeof(instance_t)); - - major_version_t its_major; - std::memcpy(&its_major, &_data[i], sizeof(major_version_t)); - i += uint32_t(sizeof(major_version_t)); - - minor_version_t its_minor; - std::memcpy(&its_minor, &_data[i], sizeof(minor_version_t)); - i += uint32_t(sizeof(minor_version_t)); - - its_offered_services_info.push_back(std::make_pair(its_service, its_instance)); - } - } - host_->on_offered_services_info(its_offered_services_info); -} - -void routing_manager_proxy::reconnect(const std::unordered_set &_clients) { - auto its_security = security_impl::get(); - if (!its_security) - return; - - // inform host about its own registration state changes - host_->on_state(static_cast(inner_state_type_e::ST_DEREGISTERED)); - - { - std::lock_guard its_lock(state_mutex_); - state_ = inner_state_type_e::ST_DEREGISTERED; - // Notify stop() call about clean deregistration - state_condition_.notify_one(); - } - - - // Remove all local connections/endpoints - for (const auto& its_client : _clients) { - if (its_client != VSOMEIP_ROUTING_CLIENT) { - remove_local(its_client, true); - } - } - - VSOMEIP_INFO << std::hex << "Application/Client " << get_client() - <<": Reconnecting to routing manager."; - -#ifndef _WIN32 - if (!its_security->check_credentials(get_client(), own_uid_, own_gid_)) { - VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() - << " : routing_manager_proxy::reconnect: isn't allowed" - << " to use the server endpoint due to credential check failed!"; - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->stop(); - } - return; - } -#endif - - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->restart(); - } -} - -void routing_manager_proxy::assign_client() { - std::vector its_command; - - std::string its_name(host_->get_name()); - uint32_t its_size(static_cast(its_name.size())); - its_command.resize(7 + its_name.size()); - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_ASSIGN_CLIENT; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - if (0 < its_name.size()) - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], its_name.c_str(), - its_name.size()); - - std::lock_guard its_state_lock(state_mutex_); - if (is_connected_) { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - if (state_ != inner_state_type_e::ST_DEREGISTERED) - return; - state_ = inner_state_type_e::ST_ASSIGNING; - - sender_->send(&its_command[0], static_cast(its_command.size())); - - boost::system::error_code ec; - register_application_timer_.cancel(ec); - register_application_timer_.expires_from_now(std::chrono::milliseconds(10000)); - register_application_timer_.async_wait( - std::bind( - &routing_manager_proxy::assign_client_timeout_cbk, - std::dynamic_pointer_cast(shared_from_this()), - std::placeholders::_1)); - } - } -} - -void routing_manager_proxy::register_application() { - byte_t its_command[] = { - VSOMEIP_REGISTER_APPLICATION, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - - if (is_connected_) { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - state_ = inner_state_type_e::ST_REGISTERING; - sender_->send(its_command, sizeof(its_command)); - - register_application_timer_.cancel(); - register_application_timer_.expires_from_now(std::chrono::milliseconds(1000)); - register_application_timer_.async_wait( - std::bind( - &routing_manager_proxy::register_application_timeout_cbk, - std::dynamic_pointer_cast(shared_from_this()), - std::placeholders::_1)); - } - } -} - -void routing_manager_proxy::deregister_application() { - std::vector its_command(VSOMEIP_COMMAND_HEADER_SIZE, 0); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_DEREGISTER_APPLICATION; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - if (is_connected_) - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(&its_command[0], uint32_t(its_command.size())); - } - } -} - -void routing_manager_proxy::send_pong() const { - byte_t its_pong[] = { - VSOMEIP_PONG, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; - - std::memcpy(&its_pong[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_t)); - - if (is_connected_) { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_pong, sizeof(its_pong)); - } - } -} - -void routing_manager_proxy::send_request_services(std::set& _requests) { - if (!_requests.size()) { - return; - } - size_t its_size = (VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE) * _requests.size(); - if (its_size > (std::numeric_limits::max)()) { - VSOMEIP_ERROR<< "routing_manager_proxy::send_request_services too many" - << " requests (" << std::dec << its_size << "), returning."; - return; - } - - std::vector its_command(its_size + VSOMEIP_COMMAND_HEADER_SIZE); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REQUEST_SERVICE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], - &client_, sizeof(client_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], - &its_size, sizeof(std::uint32_t)); - - uint32_t entry_size = (sizeof(service_t) + sizeof(instance_t) - + sizeof(major_version_t) + sizeof(minor_version_t)); - - unsigned int i = 0; - for (auto its_service : _requests) { - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + (i * entry_size)], - &its_service.service_, sizeof(its_service.service_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2 + (i * entry_size)], - &its_service.instance_, sizeof(its_service.instance_)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4 + (i * entry_size)] = its_service.major_; - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5 + (i * entry_size)], - &its_service.minor_, sizeof(its_service.minor_)); - ++i; - } - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(&its_command[0], - static_cast(its_size + VSOMEIP_COMMAND_HEADER_SIZE)); - } - } -} - -void routing_manager_proxy::send_release_service(client_t _client, service_t _service, - instance_t _instance) { - (void)_client; - byte_t its_command[VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_RELEASE_SERVICE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(client_)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::send_register_event(client_t _client, - service_t _service, instance_t _instance, - event_t _notifier, - const std::set &_eventgroups, const event_type_e _type, - reliability_type_e _reliability, - bool _is_provided) { - - std::size_t its_eventgroups_size = (_eventgroups.size() * sizeof(eventgroup_t)) + - VSOMEIP_REGISTER_EVENT_COMMAND_SIZE; - if (its_eventgroups_size > (std::numeric_limits::max)()) { - VSOMEIP_ERROR<< "routing_manager_proxy::send_register_event too many" - << " eventgroups (" << std::dec << its_eventgroups_size << "), returning."; - return; - } - byte_t *its_command = new byte_t[its_eventgroups_size]; - uint32_t its_size = static_cast(its_eventgroups_size) - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REGISTER_EVENT; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_notifier, - sizeof(_notifier)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] - = static_cast(_type); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7] - = static_cast(_is_provided); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8] - = static_cast(_reliability); - - std::size_t i = 9; - for (auto eg : _eventgroups) { - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + i], &eg, - sizeof(eventgroup_t)); - i += sizeof(eventgroup_t); - } - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, static_cast(its_eventgroups_size)); - } - } - - if (_is_provided) { - VSOMEIP_INFO << "REGISTER EVENT(" - << std::hex << std::setw(4) << std::setfill('0') << client_ << "): [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _notifier - << ":is_provider=" << _is_provided << "]"; - } - - delete[] its_command; -} - -void routing_manager_proxy::on_subscribe_ack(client_t _client, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { - (void)_client; -#if 0 - VSOMEIP_ERROR << "routing_manager_proxy::" << __func__ - << "(" << std::hex << host_->get_client() << "):" - << "event=" - << std::hex << _service << "." - << std::hex << _instance << "." - << std::hex << _eventgroup << "." - << std::hex << _event; -#endif - if (_event == ANY_EVENT) { - auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); - if (its_eventgroup) { - for (const auto& its_event : its_eventgroup->get_events()) { - host_->on_subscription_status(_service, _instance, _eventgroup, its_event->get_event(), 0x0 /*OK*/); - } - } - } else { - host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /*OK*/); - } -} - -void routing_manager_proxy::on_subscribe_nack(client_t _client, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { - (void)_client; - if (_event == ANY_EVENT) { - auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); - if (its_eventgroup) { - for (const auto& its_event : its_eventgroup->get_events()) { - host_->on_subscription_status(_service, _instance, _eventgroup, its_event->get_event(), 0x7 /*Rejected*/); - } - } - } else { - host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x7 /*Rejected*/); - } -} - -void routing_manager_proxy::cache_event_payload( - const std::shared_ptr &_message) { - const service_t its_service(_message->get_service()); - const instance_t its_instance(_message->get_instance()); - const method_t its_method(_message->get_method()); - std::shared_ptr its_event = find_event(its_service, its_instance, its_method); - if (its_event) { - if (its_event->is_field()) { - its_event->set_payload_dont_notify(_message->get_payload()); - } - } else { - // we received a event which was not yet requested - std::set its_eventgroups; - // create a placeholder field until someone requests this event with - // full information like eventgroup, field or not etc. - routing_manager_base::register_event(host_->get_client(), - its_service, its_instance, - its_method, - its_eventgroups, event_type_e::ET_UNKNOWN, - reliability_type_e::RT_UNKNOWN, - std::chrono::milliseconds::zero(), false, true, - nullptr, - false, false, true); - std::shared_ptr its_event = find_event(its_service, its_instance, its_method); - if (its_event) { - its_event->set_payload_dont_notify(_message->get_payload()); - } - } - -} - -void routing_manager_proxy::on_stop_offer_service(service_t _service, - instance_t _instance, - major_version_t _major, - minor_version_t _minor) { - (void) _major; - (void) _minor; - std::map > events; - { - std::lock_guard its_lock(events_mutex_); - auto its_events_service = events_.find(_service); - if (its_events_service != events_.end()) { - auto its_events_instance = its_events_service->second.find(_instance); - if (its_events_instance != its_events_service->second.end()) { - for (auto &e : its_events_instance->second) - events[e.first] = e.second; - } - } - } - for (auto &e : events) { - e.second->unset_payload(); - } -} - -void routing_manager_proxy::send_pending_commands() { - for (auto &po : pending_offers_) - send_offer_service(client_, - po.service_, po.instance_, - po.major_, po.minor_); - - for (auto &per : pending_event_registrations_) - send_register_event(client_, - per.service_, per.instance_, - per.notifier_, - per.eventgroups_, per.type_, per.reliability_, - per.is_provided_); - - send_request_services(requests_); -} - -void routing_manager_proxy::init_receiver() { -#ifndef _WIN32 - auto its_security = security_impl::get(); - if (!its_security) - return; - - its_security->store_client_to_uid_gid_mapping(get_client(), own_uid_, own_gid_); - its_security->store_uid_gid_to_client_mapping(own_uid_, own_gid_, get_client()); -#endif - receiver_ = ep_mgr_->create_local_server(shared_from_this()); -} - -void routing_manager_proxy::notify_remote_initially(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, const std::set &_events_to_exclude) { - auto its_eventgroup = find_eventgroup(_service, _instance, _eventgroup); - if (its_eventgroup) { - auto service_info = find_service(_service, _instance); - for (const auto &e : its_eventgroup->get_events()) { - if (e->is_field() && e->is_set() - && _events_to_exclude.find(e->get_event()) - == _events_to_exclude.end()) { - std::shared_ptr its_notification - = runtime::get()->create_notification(); - its_notification->set_service(_service); - its_notification->set_instance(_instance); - its_notification->set_method(e->get_event()); - its_notification->set_payload(e->get_payload()); - if (service_info) { - its_notification->set_interface_version(service_info->get_major()); - } - - std::shared_ptr its_serializer(get_serializer()); - if (its_serializer->serialize(its_notification.get())) { - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - send_local(sender_, VSOMEIP_ROUTING_CLIENT, its_serializer->get_data(), - its_serializer->get_size(), _instance, false, VSOMEIP_NOTIFY); - } - } - its_serializer->reset(); - put_serializer(its_serializer); - } else { - VSOMEIP_ERROR << "Failed to serialize message. Check message size!"; - } - } - } - } - -} - -uint32_t routing_manager_proxy::get_remote_subscriber_count(service_t _service, - instance_t _instance, eventgroup_t _eventgroup, bool _increment) { - std::lock_guard its_lock(remote_subscriber_count_mutex_); - uint32_t count (0); - bool found(false); - auto found_service = remote_subscriber_count_.find(_service); - if (found_service != remote_subscriber_count_.end()) { - auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - auto found_group = found_instance->second.find(_eventgroup); - if (found_group != found_instance->second.end()) { - found = true; - if (_increment) { - found_group->second = found_group->second + 1; - } else { - if (found_group->second > 0) { - found_group->second = found_group->second - 1; - } - } - count = found_group->second; - } - } - } - if (!found) { - if (_increment) { - remote_subscriber_count_[_service][_instance][_eventgroup] = 1; - count = 1; - } - } - return count; -} - -void routing_manager_proxy::clear_remote_subscriber_count( - service_t _service, instance_t _instance) { - std::lock_guard its_lock(remote_subscriber_count_mutex_); - auto found_service = remote_subscriber_count_.find(_service); - if (found_service != remote_subscriber_count_.end()) { - if (found_service->second.erase(_instance)) { - if (!found_service->second.size()) { - remote_subscriber_count_.erase(found_service); - } - } - } -} - -void -routing_manager_proxy::assign_client_timeout_cbk( - boost::system::error_code const &_error) { - if (!_error) { - bool register_again(false); - { - std::lock_guard its_lock(state_mutex_); - if (state_ != inner_state_type_e::ST_REGISTERED) { - state_ = inner_state_type_e::ST_DEREGISTERED; - register_again = true; - } - } - if (register_again) { - std::lock_guard its_lock(sender_mutex_); - VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() - << " request client timeout! Trying again..."; - - if (sender_) { - sender_->restart(); - } - } - } -} - -void routing_manager_proxy::register_application_timeout_cbk( - boost::system::error_code const &_error) { - - bool register_again(false); - { - std::lock_guard its_lock(state_mutex_); - if (!_error && state_ != inner_state_type_e::ST_REGISTERED) { - state_ = inner_state_type_e::ST_DEREGISTERED; - register_again = true; - } - } - if (register_again) { - std::lock_guard its_lock(sender_mutex_); - VSOMEIP_WARNING << std::hex << "Client 0x" << get_client() - << " register timeout! Trying again..."; - - if (sender_) - sender_->restart(); - } -} - -void routing_manager_proxy::send_registered_ack() { - byte_t its_command[VSOMEIP_COMMAND_HEADER_SIZE] = { - VSOMEIP_REGISTERED_ACK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - client_t client = get_client(); - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client, - sizeof(client)); - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, VSOMEIP_COMMAND_HEADER_SIZE); - } - } -} - -bool routing_manager_proxy::is_client_known(client_t _client) { - std::lock_guard its_lock(known_clients_mutex_); - return (known_clients_.find(_client) != known_clients_.end()); -} - -bool routing_manager_proxy::create_placeholder_event_and_subscribe( - service_t _service, instance_t _instance, - eventgroup_t _eventgroup, event_t _notifier, client_t _client) { - - std::lock_guard its_lock(stop_mutex_); - - bool is_inserted(false); - - if (find_service(_service, _instance)) { - // We received an event for an existing service which was not yet - // requested/offered. Create a placeholder field until someone - // requests/offers this event with full information like eventgroup, - // field/event, etc. - std::set its_eventgroups({ _eventgroup }); - // routing_manager_proxy: Always register with own client id and shadow = false - routing_manager_base::register_event(host_->get_client(), - _service, _instance, _notifier, - its_eventgroups, event_type_e::ET_UNKNOWN, reliability_type_e::RT_UNKNOWN, - std::chrono::milliseconds::zero(), false, true, nullptr, false, false, - true); - - std::shared_ptr its_event = find_event(_service, _instance, _notifier); - if (its_event) { - is_inserted = its_event->add_subscriber(_eventgroup, _client, false); - } - } - - return is_inserted; -} - -void routing_manager_proxy::request_debounce_timeout_cbk( - boost::system::error_code const &_error) { - std::lock_guard its_lock(state_mutex_); - if (!_error) { - if (requests_to_debounce_.size()) { - if (state_ == inner_state_type_e::ST_REGISTERED) { - send_request_services(requests_to_debounce_); - requests_.insert(requests_to_debounce_.begin(), - requests_to_debounce_.end()); - requests_to_debounce_.clear(); - } else { - { - std::lock_guard its_lock(request_timer_mutex_); - request_debounce_timer_running_ = true; - request_debounce_timer_.expires_from_now(std::chrono::milliseconds( - configuration_->get_request_debouncing(host_->get_name()))); - request_debounce_timer_.async_wait( - std::bind( - &routing_manager_proxy::request_debounce_timeout_cbk, - std::dynamic_pointer_cast(shared_from_this()), - std::placeholders::_1)); - return; - } - } - } - } - { - std::lock_guard its_lock(request_timer_mutex_); - request_debounce_timer_running_ = false; - } -} - -void routing_manager_proxy::register_client_error_handler(client_t _client, - const std::shared_ptr &_endpoint) { - _endpoint->register_error_handler( - std::bind(&routing_manager_proxy::handle_client_error, this, _client)); -} - -void routing_manager_proxy::handle_client_error(client_t _client) { - if (_client != VSOMEIP_ROUTING_CLIENT) { - VSOMEIP_INFO << "Client 0x" << std::hex << get_client() - << " handles a client error(" << std::hex << _client << ")"; - remove_local(_client, true); - } else { - bool should_reconnect(true); - { - std::unique_lock its_lock(state_mutex_); - should_reconnect = is_started_; - } - if (should_reconnect) { - std::unordered_set its_known_clients; - { - std::lock_guard its_lock(known_clients_mutex_); - its_known_clients = known_clients_; - } - reconnect(its_known_clients); - } - } -} - -void routing_manager_proxy::send_get_offered_services_info(client_t _client, offer_type_e _offer_type) { - (void)_client; - - byte_t its_command[VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_OFFERED_SERVICES_REQUEST; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_offer_type, - sizeof(_offer_type)); - - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } -} - -void routing_manager_proxy::send_unsubscribe_ack( - service_t _service, instance_t _instance, eventgroup_t _eventgroup, - remote_subscription_id_t _id) { - byte_t its_command[VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE]; - const std::uint32_t its_size = VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - const client_t its_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNSUBSCRIBE_ACK; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client, - sizeof(its_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_id, - sizeof(_id)); - - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::resend_provided_event_registrations() { - std::lock_guard its_lock(state_mutex_); - for (const event_data_t& ed : pending_event_registrations_) { - if (ed.is_provided_) { - send_register_event(client_, ed.service_, ed.instance_, - ed.notifier_, ed.eventgroups_, ed.type_, ed.reliability_, - ed.is_provided_); - } - } -} - -void routing_manager_proxy::send_resend_provided_event_response(pending_remote_offer_id_t _id) { - byte_t its_command[VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE]; - const std::uint32_t its_size = VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - const client_t its_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_RESEND_PROVIDED_EVENTS; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client, - sizeof(its_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_id, - sizeof(pending_remote_offer_id_t)); - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::send_update_security_policy_response(pending_security_update_id_t _update_id) { - byte_t its_command[VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE]; - const std::uint32_t its_size = VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - const client_t its_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client, - sizeof(its_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_update_id, - sizeof(pending_security_update_id_t)); - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::send_remove_security_policy_response(pending_security_update_id_t _update_id) { - byte_t its_command[VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE]; - const std::uint32_t its_size = VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - const client_t its_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &its_client, - sizeof(its_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_update_id, - sizeof(pending_security_update_id_t)); - { - std::lock_guard its_lock(sender_mutex_); - if (sender_) { - sender_->send(its_command, sizeof(its_command)); - } - } -} - -void routing_manager_proxy::on_update_security_credentials(const byte_t *_data, uint32_t _size) { - auto its_security = security_impl::get(); - if (!its_security) - return; - - uint32_t i = 0; - while ( (i + sizeof(uint32_t) + sizeof(uint32_t)) <= _size) { - std::shared_ptr its_policy(std::make_shared()); - - boost::icl::interval_set its_gid_set; - uint32_t its_uid, its_gid; - - std::memcpy(&its_uid, &_data[i], sizeof(uint32_t)); - i += uint32_t(sizeof(uint32_t)); - std::memcpy(&its_gid, &_data[i], sizeof(uint32_t)); - i += uint32_t(sizeof(uint32_t)); - - its_gid_set.insert(its_gid); - - its_policy->credentials_ += std::make_pair( - boost::icl::interval::closed(its_uid, its_uid), its_gid_set); - its_policy->allow_who_ = true; - its_policy->allow_what_ = true; - - its_security->add_security_credentials(its_uid, its_gid, its_policy, get_client()); - } -} - -void routing_manager_proxy::on_client_assign_ack(const client_t &_client) { - std::lock_guard its_lock(state_mutex_); - if (state_ == inner_state_type_e::ST_ASSIGNING) { - if (_client != VSOMEIP_CLIENT_UNSET) { - state_ = inner_state_type_e::ST_ASSIGNED; - - boost::system::error_code ec; - register_application_timer_.cancel(ec); - host_->set_client(_client); - client_ = _client; - - if (is_started_) { - init_receiver(); - if (receiver_) { - receiver_->start(); - - VSOMEIP_INFO << std::hex << "Client " << client_ - << " (" << host_->get_name() - << ") successfully connected to routing ~> registering.."; - register_application(); - } else { - state_ = inner_state_type_e::ST_DEREGISTERED; - - host_->set_client(VSOMEIP_CLIENT_UNSET); - client_ = VSOMEIP_CLIENT_UNSET; - - sender_->restart(); - } - } - } else { - VSOMEIP_ERROR << "Didn't receive valid clientID! Won't register application."; - } - } else { - VSOMEIP_WARNING << "Client " << std::hex << client_ - << " received another client identifier (" - << std::hex << _client - << "). Ignoring it. (" - << (int)state_ << ")"; - } -} - -void routing_manager_proxy::on_suspend() { - - VSOMEIP_INFO << __func__ << ": Application " - << std::hex << std::setw(4) << std::setfill('0') - << host_->get_client(); - - std::lock_guard its_lock(remote_subscriber_count_mutex_); - - // Unsubscribe everything that is left over. - for (const auto &s : remote_subscriber_count_) { - for (const auto &i : s.second) { - for (const auto e : i.second) - routing_manager_base::unsubscribe( - VSOMEIP_ROUTING_CLIENT, ANY_UID, ANY_GID, - s.first, i.first, e.first, ANY_EVENT); - } - } - - // Remove all entries. - remote_subscriber_count_.clear(); -} - -} // namespace vsomeip_v3 diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp index 406b0d9..16ad36d 100644 --- a/implementation/routing/src/routing_manager_stub.cpp +++ b/implementation/routing/src/routing_manager_stub.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,28 +11,56 @@ #include #include +#include +#include #include #include -#include +#include #include #include "../include/routing_manager_stub.hpp" #include "../include/routing_manager_stub_host.hpp" #include "../include/remote_subscription.hpp" #include "../../configuration/include/configuration.hpp" -#include "../../security/include/security.hpp" - -#include "../../endpoints/include/local_server_endpoint_impl.hpp" #include "../../endpoints/include/endpoint_manager_impl.hpp" +#include "../../endpoints/include/netlink_connector.hpp" +#include "../../protocol/include/deregister_application_command.hpp" +#include "../../protocol/include/distribute_security_policies_command.hpp" +#include "../../protocol/include/dummy_command.hpp" +#include "../../protocol/include/expire_command.hpp" +#include "../../protocol/include/offer_service_command.hpp" +#include "../../protocol/include/offered_services_request_command.hpp" +#include "../../protocol/include/offered_services_response_command.hpp" +#include "../../protocol/include/ping_command.hpp" +#include "../../protocol/include/pong_command.hpp" +#include "../../protocol/include/register_application_command.hpp" +#include "../../protocol/include/register_events_command.hpp" +#include "../../protocol/include/registered_ack_command.hpp" +#include "../../protocol/include/release_service_command.hpp" +#include "../../protocol/include/remove_security_policy_command.hpp" +#include "../../protocol/include/remove_security_policy_response_command.hpp" +#include "../../protocol/include/request_service_command.hpp" +#include "../../protocol/include/resend_provided_events_command.hpp" +#include "../../protocol/include/routing_info_command.hpp" +#include "../../protocol/include/send_command.hpp" +#include "../../protocol/include/stop_offer_service_command.hpp" +#include "../../protocol/include/subscribe_ack_command.hpp" +#include "../../protocol/include/subscribe_command.hpp" +#include "../../protocol/include/subscribe_nack_command.hpp" +#include "../../protocol/include/suspend_command.hpp" +#include "../../protocol/include/unregister_event_command.hpp" +#include "../../protocol/include/unsubscribe_ack_command.hpp" +#include "../../protocol/include/unsubscribe_command.hpp" +#include "../../protocol/include/update_security_credentials_command.hpp" +#include "../../protocol/include/update_security_policy_command.hpp" +#include "../../protocol/include/update_security_policy_response_command.hpp" +#include "../../security/include/policy_manager_impl.hpp" +#include "../../security/include/security.hpp" #include "../../utility/include/byteorder.hpp" #include "../../utility/include/utility.hpp" -#include "../implementation/message/include/payload_impl.hpp" namespace vsomeip_v3 { -const std::vector routing_manager_stub::its_ping_( - { VSOMEIP_PING, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); - routing_manager_stub::routing_manager_stub( routing_manager_stub_host *_host, const std::shared_ptr& _configuration) : @@ -40,7 +68,7 @@ routing_manager_stub::routing_manager_stub( io_(_host->get_io()), watchdog_timer_(_host->get_io()), client_id_timer_(_host->get_io()), - endpoint_(nullptr), + root_(nullptr), local_receiver_(nullptr), configuration_(_configuration), is_socket_activated_(false), @@ -48,20 +76,31 @@ routing_manager_stub::routing_manager_stub( max_local_message_size_(configuration_->get_max_message_size_local()), configured_watchdog_timeout_(configuration_->get_watchdog_timeout()), pinged_clients_timer_(io_), - pending_security_update_id_(0) { + pending_security_update_id_(0) +#if defined(__linux__) || defined(ANDROID) + , is_local_link_available_(false) +#endif +{ } routing_manager_stub::~routing_manager_stub() { } void routing_manager_stub::init() { + init_routing_endpoint(); + + std::string its_env; + char its_hostname[1024]; + if (gethostname(its_hostname, sizeof(its_hostname)) == 0) + its_env = its_hostname; + host_->set_client_host(its_env); } void routing_manager_stub::start() { { std::lock_guard its_lock(used_client_ids_mutex_); - used_client_ids_ = utility::get_used_client_ids(); + used_client_ids_ = utility::get_used_client_ids(configuration_->get_network()); // Wait VSOMEIP_MAX_CONNECT_TIMEOUT * 2 and expect after that time // that all client_ids are used have to be connected to the routing. // Otherwise they can be marked as "erroneous client". @@ -73,12 +112,23 @@ void routing_manager_stub::start() { std::placeholders::_1)); } - if (!endpoint_) { - // application has been stopped and started again - init_routing_endpoint(); - } - if (endpoint_) { - endpoint_->start(); +#if defined(__linux__) || defined(ANDROID) + if (configuration_->is_local_routing()) { +#else + { +#endif // __linux__ || ANDROID + if (!root_) { + // application has been stopped and started again + init_routing_endpoint(); + } + if (root_) { + root_->start(); + } +#if defined(__linux__) || defined(ANDROID) + } else { + if (local_link_connector_) + local_link_connector_->start(); +#endif } client_registration_running_ = true; @@ -122,47 +172,60 @@ void routing_manager_stub::stop() { client_id_timer_.cancel(); } - if( !is_socket_activated_) { - endpoint_->stop(); - endpoint_ = nullptr; - std::stringstream its_endpoint_path; - its_endpoint_path << utility::get_base_path(configuration_) << std::hex - << VSOMEIP_ROUTING_CLIENT; -#ifdef _WIN32 - ::_unlink(its_endpoint_path.str().c_str()); -#else - if (-1 == ::unlink(its_endpoint_path.str().c_str())) { - VSOMEIP_ERROR << "routing_manager_stub::stop() unlink failed (" - << its_endpoint_path.str() << "): "<< std::strerror(errno); + bool is_local_routing(configuration_->is_local_routing()); + +#if defined(__linux__) || defined(ANDROID) + if (local_link_connector_) + local_link_connector_->stop(); +#endif // __linux__ || ANDROID + + if (!is_socket_activated_) { + root_->stop(); + root_ = nullptr; + + if (is_local_routing) { + std::stringstream its_endpoint_path; + its_endpoint_path << utility::get_base_path(configuration_->get_network()) + << std::hex << VSOMEIP_ROUTING_CLIENT; + #ifdef _WIN32 + ::_unlink(its_endpoint_path.str().c_str()); + #else + if (-1 == ::unlink(its_endpoint_path.str().c_str())) { + VSOMEIP_ERROR << "routing_manager_stub::stop() unlink failed (" + << its_endpoint_path.str() << "): "<< std::strerror(errno); + } + #endif } -#endif } - if(local_receiver_) { + if (local_receiver_) { local_receiver_->stop(); local_receiver_ = nullptr; - std::stringstream its_local_receiver_path; - its_local_receiver_path << utility::get_base_path(configuration_) - << std::hex << host_->get_client(); + + if (is_local_routing) { + std::stringstream its_local_receiver_path; + its_local_receiver_path << utility::get_base_path(configuration_->get_network()) + << std::hex << host_->get_client(); #ifdef _WIN32 - ::_unlink(its_local_receiver_path.str().c_str()); + ::_unlink(its_local_receiver_path.str().c_str()); #else - if (-1 == ::unlink(its_local_receiver_path.str().c_str())) { - VSOMEIP_ERROR << "routing_manager_stub::stop() unlink (local receiver) failed (" - << its_local_receiver_path.str() << "): "<< std::strerror(errno); - } + if (-1 == ::unlink(its_local_receiver_path.str().c_str())) { + VSOMEIP_ERROR << "routing_manager_stub::stop() unlink (local receiver) failed (" + << its_local_receiver_path.str() << "): "<< std::strerror(errno); + } #endif + } } } void routing_manager_stub::on_message(const byte_t *_data, length_t _size, - endpoint *_receiver, const boost::asio::ip::address &_destination, - client_t _bound_client, - credentials_t _credentials, + endpoint *_receiver, bool _is_multicast, + client_t _bound_client, const vsomeip_sec_client_t *_sec_client, const boost::asio::ip::address &_remote_address, std::uint16_t _remote_port) { + (void)_receiver; - (void)_destination; + (void)_is_multicast; (void)_remote_address; (void) _remote_port; #if 0 @@ -173,97 +236,118 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, VSOMEIP_INFO << msg.str(); #endif - std::uint32_t its_sender_uid = std::get<0>(_credentials); - std::uint32_t its_sender_gid = std::get<1>(_credentials); - - if (VSOMEIP_COMMAND_SIZE_POS_MAX < _size) { - byte_t its_command; - client_t its_client; - std::string its_client_endpoint; - service_t its_service; - instance_t its_instance; - method_t its_method; - eventgroup_t its_eventgroup; - event_t its_notifier; - event_type_e its_event_type; - bool is_provided(false); - major_version_t its_major; - minor_version_t its_minor; - std::shared_ptr its_payload; - const byte_t *its_data; - uint32_t its_size; - bool its_reliable(false); - client_t its_client_from_header; - client_t its_target_client; - client_t its_subscriber; - uint8_t its_check_status(0); - std::uint16_t its_subscription_id(PENDING_SUBSCRIPTION_ID); - offer_type_e its_offer_type; - - its_command = _data[VSOMEIP_COMMAND_TYPE_POS]; - std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS], - sizeof(its_client)); - - if (security::get()->is_enabled() && _bound_client != its_client) { - VSOMEIP_WARNING << "vSomeIP Security: routing_manager_stub::on_message: " - << "Routing Manager received a message from client " - << std::hex << std::setw(4) << std::setfill('0') - << its_client << " with command " << (uint32_t)its_command - << " which doesn't match the bound client " - << std::setw(4) << std::setfill('0') << _bound_client - << " ~> skip message!"; - return; - } + client_t its_client; + protocol::id_e its_id; + std::string its_client_endpoint; + service_t its_service; + instance_t its_instance; + method_t its_method; + eventgroup_t its_eventgroup; + event_t its_notifier; + major_version_t its_major; + minor_version_t its_minor; + std::shared_ptr its_payload; + bool is_reliable(false); + client_t its_subscriber; + uint8_t its_check_status(0); + std::uint16_t its_subscription_id(PENDING_SUBSCRIPTION_ID); + port_t its_port(ILLEGAL_PORT); + + std::vector its_buffer(_data, _data + _size); + protocol::error_e its_error; + + // Use dummy command to deserialize id and client. + protocol::dummy_command its_base_command; + its_base_command.deserialize(its_buffer, its_error); + if (its_error != protocol::error_e::ERROR_OK) { - std::memcpy(&its_size, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN], - sizeof(its_size)); + VSOMEIP_ERROR << __func__ + << ": deserialization of command and client identifier failed (" + << std::dec << static_cast(its_error) + << ")"; + return; + } - if (its_size <= _size - VSOMEIP_COMMAND_HEADER_SIZE) { - switch (its_command) { - case VSOMEIP_REGISTER_APPLICATION: - if (_size != VSOMEIP_REGISTER_APPLICATION_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a REGISTER_APPLICATION command with wrong size ~> skip!"; - break; - } - update_registration(its_client, registration_type_e::REGISTER); - break; + its_client = its_base_command.get_client(); + its_id = its_base_command.get_id(); - case VSOMEIP_DEREGISTER_APPLICATION: - if (_size != VSOMEIP_DEREGISTER_APPLICATION_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a DEREGISTER_APPLICATION command with wrong size ~> skip!"; - break; - } - update_registration(its_client, registration_type_e::DEREGISTER); - break; + if (configuration_->is_security_enabled() + && configuration_->is_local_routing() + && _bound_client != its_client) { + VSOMEIP_WARNING << "vSomeIP Security: routing_manager_stub::on_message: " + << "Routing Manager received a message from client " + << std::hex << std::setw(4) << std::setfill('0') + << its_client << " with command " << (uint32_t)its_id + << " which doesn't match the bound client " + << std::setw(4) << std::setfill('0') << _bound_client + << " ~> skip message!"; + return; + } - case VSOMEIP_PONG: - if (_size != VSOMEIP_PONG_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a PONG command with wrong size ~> skip!"; - break; - } + switch (its_id) { + + case protocol::id_e::REGISTER_APPLICATION_ID: + { + protocol::register_application_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) + update_registration(its_command.get_client(), + registration_type_e::REGISTER, + _remote_address, its_command.get_port()); + else + VSOMEIP_ERROR << __func__ + << ": deserializing register application failed (" + << std::dec << static_cast(its_error) << ")"; + + break; + } + + case protocol::id_e::DEREGISTER_APPLICATION_ID: + { + protocol::deregister_application_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) + update_registration(its_command.get_client(), + registration_type_e::DEREGISTER, + _remote_address, its_port); + else + VSOMEIP_ERROR << __func__ + << ": deserializing register application failed (" + << std::dec << static_cast(its_error) << ")"; + + break; + } + + case protocol::id_e::PONG_ID: + { + protocol::pong_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { on_pong(its_client); VSOMEIP_TRACE << "PONG(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << ")"; - break; - - case VSOMEIP_OFFER_SERVICE: - if (_size != VSOMEIP_OFFER_SERVICE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a OFFER_SERVICE command with wrong size ~> skip!"; - break; - } + << std::hex << std::setw(4) << std::setfill('0') + << its_client << ")"; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing pong failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_major)); - std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5], - sizeof(its_minor)); - - if (security::get()->is_offer_allowed(its_sender_uid, its_sender_gid, - its_client, its_service, its_instance)) { + case protocol::id_e::OFFER_SERVICE_ID: + { + protocol::offer_service_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_major = its_command.get_major(); + its_minor = its_command.get_minor(); + + if (VSOMEIP_SEC_OK == security::is_client_allowed_to_offer( + _sec_client, its_service, its_instance)) { host_->offer_service(its_client, its_service, its_instance, its_major, its_minor); } else { @@ -272,48 +356,54 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, << "the following service/instance " << its_service << "/" << its_instance << " ~> Skip offer!"; } - break; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing offer service failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } - case VSOMEIP_STOP_OFFER_SERVICE: - if (_size != VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a STOP_OFFER_SERVICE command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_major)); - std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5], - sizeof(its_minor)); - - host_->stop_offer_service(its_client, its_service, its_instance, its_major, its_minor); - break; - - case VSOMEIP_SUBSCRIBE: - if (_size != VSOMEIP_SUBSCRIBE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a SUBSCRIBE command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_major)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7], - sizeof(its_notifier)); + case protocol::id_e::STOP_OFFER_SERVICE_ID: + { + protocol::stop_offer_service_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_major = its_command.get_major(); + its_minor = its_command.get_minor(); + + host_->stop_offer_service(its_client, + its_service, its_instance, + its_major, its_minor); + } else + VSOMEIP_ERROR << __func__ + << ": deserializing stop offer service failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::SUBSCRIBE_ID: + { + protocol::subscribe_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_major = its_command.get_major(); + its_notifier = its_command.get_event(); + auto its_filter = its_command.get_filter(); if (its_notifier == ANY_EVENT) { - if (host_->is_subscribe_to_any_event_allowed(_credentials, its_client, its_service, + if (host_->is_subscribe_to_any_event_allowed(_sec_client, its_client, its_service, its_instance, its_eventgroup)) { - host_->subscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance, - its_eventgroup, its_major, its_notifier); + host_->subscribe(its_client, _sec_client, its_service, its_instance, + its_eventgroup, its_major, its_notifier, its_filter); } else { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client << " : routing_manager_stub::on_message: " @@ -322,10 +412,10 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, << " which violates the security policy ~> Skip subscribe!"; } } else { - if (security::get()->is_client_allowed(its_sender_uid, its_sender_gid, - its_client, its_service, its_instance, its_notifier)) { - host_->subscribe(its_client, its_sender_uid, its_sender_gid, its_service, its_instance, - its_eventgroup, its_major, its_notifier); + if (VSOMEIP_SEC_OK == security::is_client_allowed_to_access_member( + _sec_client, its_service, its_instance, its_notifier)) { + host_->subscribe(its_client, _sec_client, its_service, its_instance, + its_eventgroup, its_major, its_notifier, its_filter); } else { VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client << " : routing_manager_stub::on_message: " @@ -334,456 +424,397 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, << " which violates the security policy ~> Skip subscribe!"; } } - break; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing subscribe failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::UNSUBSCRIBE_ID: + { + protocol::unsubscribe_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_notifier = its_command.get_event(); + + host_->unsubscribe(its_client, _sec_client, + its_service, its_instance, its_eventgroup, its_notifier); + } else + VSOMEIP_ERROR << __func__ + << ": deserializing unsubscribe failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::SUBSCRIBE_ACK_ID: + { + protocol::subscribe_ack_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_subscriber = its_command.get_subscriber(); + its_notifier = its_command.get_event(); + its_subscription_id = its_command.get_pending_id(); - case VSOMEIP_UNSUBSCRIBE: - if (_size != VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a UNSUBSCRIBE command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_notifier)); - - host_->unsubscribe(its_client, its_sender_uid, its_sender_gid, its_service, - its_instance, its_eventgroup, its_notifier); - break; - - case VSOMEIP_SUBSCRIBE_ACK: - if (_size != VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a SUBSCRIBE_ACK command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_subscriber)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_notifier)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 10], - sizeof(its_subscription_id)); host_->on_subscribe_ack(its_subscriber, its_service, its_instance, its_eventgroup, its_notifier, its_subscription_id); + VSOMEIP_INFO << "SUBSCRIBE ACK(" << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." << std::hex << std::setw(4) << std::setfill('0') << its_notifier << "]"; - break; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing subscribe ack failed (" + << std::dec << static_cast(its_error) << ")"; + + break; + } + + case protocol::id_e::SUBSCRIBE_NACK_ID: + { + protocol::subscribe_nack_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_subscriber = its_command.get_subscriber(); + its_notifier = its_command.get_event(); + its_subscription_id = its_command.get_pending_id(); - case VSOMEIP_SUBSCRIBE_NACK: - if (_size != VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a SUBSCRIBE_NACK command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_subscriber, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_subscriber)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_notifier)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 10], - sizeof(its_subscription_id)); host_->on_subscribe_nack(its_subscriber, its_service, - its_instance, its_eventgroup, its_notifier, - its_subscription_id, false); + its_instance, its_eventgroup, its_notifier, its_subscription_id); + VSOMEIP_INFO << "SUBSCRIBE NACK(" << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "." << std::hex << std::setw(4) << std::setfill('0') << its_notifier << "]"; - break; - case VSOMEIP_UNSUBSCRIBE_ACK: - if (_size != VSOMEIP_UNSUBSCRIBE_ACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a VSOMEIP_UNSUBSCRIBE_ACK command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_eventgroup)); - std::memcpy(&its_subscription_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_subscription_id)); + } else + VSOMEIP_ERROR << __func__ + << ": deserializing subscribe nack failed (" + << std::dec << static_cast(its_error) << ")"; + + break; + } + + case protocol::id_e::UNSUBSCRIBE_ACK_ID: + { + protocol::unsubscribe_ack_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + its_service = its_command.get_service(); + its_instance = its_command.get_instance(); + its_eventgroup = its_command.get_eventgroup(); + its_subscription_id = its_command.get_pending_id(); + host_->on_unsubscribe_ack(its_client, its_service, its_instance, its_eventgroup, its_subscription_id); + VSOMEIP_INFO << "UNSUBSCRIBE ACK(" << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." << std::hex << std::setw(4) << std::setfill('0') << its_eventgroup << "]"; - break; - case VSOMEIP_SEND: { - if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a SEND command with too small size ~> skip!"; - break; - } - its_data = &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS]; - its_service = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_SERVICE_POS_MIN], - its_data[VSOMEIP_SERVICE_POS_MAX]); - its_client_from_header = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_CLIENT_POS_MIN], - its_data[VSOMEIP_CLIENT_POS_MAX]); - its_method = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_METHOD_POS_MIN], - its_data[VSOMEIP_METHOD_POS_MAX]); - std::memcpy(&its_instance, &_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN], - sizeof(its_instance)); - std::memcpy(&its_reliable, &_data[VSOMEIP_SEND_COMMAND_RELIABLE_POS], - sizeof(its_reliable)); - std::memcpy(&its_check_status, &_data[VSOMEIP_SEND_COMMAND_CHECK_STATUS_POS], - sizeof(its_check_status)); - - // Allow response messages from local proxies as answer to remote requests - // but check requests sent by local proxies to remote against policy. - if (utility::is_request(its_data[VSOMEIP_MESSAGE_TYPE_POS])) { - if (!security::get()->is_client_allowed(its_sender_uid, its_sender_gid, - its_client_from_header, its_service, its_instance, its_method)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client_from_header - << " : routing_manager_stub::on_message: " - << " isn't allowed to send a request to service/instance/method " - << its_service << "/" << its_instance << "/" << its_method - << " ~> Skip message!"; - return; - } - } - // reduce by size of instance, flush, reliable, client and is_valid_crc flag - const std::uint32_t its_message_size = its_size - - (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE); - if (its_message_size != - VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3]) - + VSOMEIP_SOMEIP_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a SEND command containing message with invalid size -> skip!"; - break; - } - host_->on_message(its_service, its_instance, its_data, its_message_size, - its_reliable, _bound_client, _credentials, its_check_status, false); - break; - } - case VSOMEIP_NOTIFY: { - if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a NOTIFY command with too small size ~> skip!"; - break; - } - its_data = &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS]; - its_service = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_SERVICE_POS_MIN], - its_data[VSOMEIP_SERVICE_POS_MAX]); - std::memcpy(&its_instance, &_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN], - sizeof(its_instance)); - // reduce by size of instance, flush, reliable, is_valid_crc flag and target client - const std::uint32_t its_message_size = its_size - - (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE); - if (its_message_size != - VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3]) - + VSOMEIP_SOMEIP_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a NOTIFY command containing message with invalid size -> skip!"; - break; - } - host_->on_notification(VSOMEIP_ROUTING_CLIENT, its_service, its_instance, its_data, its_message_size); - break; - } - case VSOMEIP_NOTIFY_ONE: { - if (_size < VSOMEIP_SEND_COMMAND_SIZE + VSOMEIP_FULL_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a NOTIFY_ONE command with too small size ~> skip!"; - break; - } - its_data = &_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS]; - its_service = VSOMEIP_BYTES_TO_WORD( - its_data[VSOMEIP_SERVICE_POS_MIN], - its_data[VSOMEIP_SERVICE_POS_MAX]); - std::memcpy(&its_instance, &_data[VSOMEIP_SEND_COMMAND_INSTANCE_POS_MIN], - sizeof(its_instance)); - std::memcpy(&its_target_client, &_data[VSOMEIP_SEND_COMMAND_DST_CLIENT_POS_MIN], - sizeof(client_t)); - // reduce by size of instance, flush, reliable flag, is_valid_crc and target client - const std::uint32_t its_message_size = its_size - - (VSOMEIP_SEND_COMMAND_SIZE - VSOMEIP_COMMAND_HEADER_SIZE); - if (its_message_size != - VSOMEIP_BYTES_TO_LONG(_data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 1], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 2], - _data[VSOMEIP_SEND_COMMAND_PAYLOAD_POS + VSOMEIP_LENGTH_POS_MIN + 3]) - + VSOMEIP_SOMEIP_HEADER_SIZE) { - VSOMEIP_WARNING << "Received a NOTIFY_ONE command containing message with invalid size -> skip!"; - break; - } - host_->on_notification(its_target_client, its_service, its_instance, - its_data, its_message_size, true); - break; - } - case VSOMEIP_REQUEST_SERVICE: - { - uint32_t entry_size = (sizeof(service_t) + sizeof(instance_t) - + sizeof(major_version_t) + sizeof(minor_version_t)); - if (its_size % entry_size > 0) { - VSOMEIP_WARNING << "Received a REQUEST_SERVICE command with invalid size -> skip!"; - break; - } - uint32_t request_count(its_size / entry_size); - std::set requests; - for (uint32_t i = 0; i < request_count; ++i) { - service_t its_service; - instance_t its_instance; - major_version_t its_major; - minor_version_t its_minor; - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + (i * entry_size)], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2 + (i * entry_size)], - sizeof(its_instance)); - std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4 + (i * entry_size)], - sizeof(its_major)); - std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5 + (i * entry_size)], - sizeof(its_minor)); - if (security::get()->is_client_allowed(its_sender_uid, its_sender_gid, - its_client, its_service, its_instance, 0x00, true)) { - host_->request_service(its_client, its_service, its_instance, - its_major, its_minor ); - service_data_t request = { - its_service, its_instance, - its_major, its_minor - }; - requests.insert(request); - } else { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex - << its_client << " : routing_manager_stub::on_message: " - << "requests service/instance " - << its_service << "/" << its_instance - << " which violates the security policy ~> Skip request!"; + } else + VSOMEIP_ERROR << __func__ + << ": deserializing unsubscribe ack failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::SEND_ID: + { + protocol::send_command its_command(its_id); + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + auto its_message_data(its_command.get_message()); + if (its_message_data.size() > VSOMEIP_MESSAGE_TYPE_POS) { + + its_service = VSOMEIP_BYTES_TO_WORD( + its_message_data[VSOMEIP_SERVICE_POS_MIN], + its_message_data[VSOMEIP_SERVICE_POS_MAX]); + its_method = VSOMEIP_BYTES_TO_WORD( + its_message_data[VSOMEIP_METHOD_POS_MIN], + its_message_data[VSOMEIP_METHOD_POS_MAX]); + its_client = VSOMEIP_BYTES_TO_WORD( + its_message_data[VSOMEIP_CLIENT_POS_MIN], + its_message_data[VSOMEIP_CLIENT_POS_MAX]); + + its_instance = its_command.get_instance(); + is_reliable = its_command.is_reliable(); + its_check_status = its_command.get_status(); + + // Allow response messages from local proxies as answer to remote requests + // but check requests sent by local proxies to remote against policy. + if (utility::is_request(its_message_data[VSOMEIP_MESSAGE_TYPE_POS])) { + if (VSOMEIP_SEC_OK != security::is_client_allowed_to_access_member( + _sec_client, its_service, its_instance, its_method)) { + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" << std::hex << its_client + << " : routing_manager_stub::on_message: " + << " isn't allowed to send a request to service/instance/method " + << its_service << "/" << its_instance << "/" << its_method + << " ~> Skip message!"; + return; } } - if (security::get()->is_enabled()) { - handle_credentials(its_client, requests); + // reduce by size of instance, flush, reliable, client and is_valid_crc flag + auto its_contained_size = VSOMEIP_BYTES_TO_LONG( + its_message_data[VSOMEIP_LENGTH_POS_MIN], + its_message_data[VSOMEIP_LENGTH_POS_MIN+1], + its_message_data[VSOMEIP_LENGTH_POS_MIN+2], + its_message_data[VSOMEIP_LENGTH_POS_MIN+3]); + if (its_message_data.size() != its_contained_size + VSOMEIP_SOMEIP_HEADER_SIZE) { + VSOMEIP_WARNING << "Received a SEND command containing message with invalid size -> skip!"; + break; } - handle_requests(its_client, requests); - break; + host_->on_message(its_service, its_instance, + &its_message_data[0], length_t(its_message_data.size()), + is_reliable, _bound_client, _sec_client, its_check_status, false); } + } + break; + } - case VSOMEIP_RELEASE_SERVICE: - if (_size != VSOMEIP_RELEASE_SERVICE_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a RELEASE_SERVICE command with wrong size ~> skip!"; + case protocol::id_e::NOTIFY_ID: + case protocol::id_e::NOTIFY_ONE_ID: + { + protocol::send_command its_command(its_id); + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + auto its_message_data(its_command.get_message()); + if (its_message_data.size() > VSOMEIP_MESSAGE_TYPE_POS) { + + its_client = its_command.get_target(); + its_service = VSOMEIP_BYTES_TO_WORD( + its_message_data[VSOMEIP_SERVICE_POS_MIN], + its_message_data[VSOMEIP_SERVICE_POS_MAX]); + its_instance = its_command.get_instance(); + + auto its_contained_size = VSOMEIP_BYTES_TO_LONG( + its_message_data[VSOMEIP_LENGTH_POS_MIN], + its_message_data[VSOMEIP_LENGTH_POS_MIN+1], + its_message_data[VSOMEIP_LENGTH_POS_MIN+2], + its_message_data[VSOMEIP_LENGTH_POS_MIN+3]); + if (its_message_data.size() != its_contained_size + VSOMEIP_SOMEIP_HEADER_SIZE) { + VSOMEIP_WARNING << "Received a NOTIFY command containing message with invalid size -> skip!"; break; } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - host_->release_service(its_client, its_service, its_instance); + host_->on_notification(its_client, its_service, its_instance, + &its_message_data[0], length_t(its_message_data.size()), + its_id == protocol::id_e::NOTIFY_ONE_ID); break; + } + } + break; + } - case VSOMEIP_REGISTER_EVENT: { - if (_size < VSOMEIP_REGISTER_EVENT_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a REGISTER_EVENT command with wrong size ~> skip!"; - break; + case protocol::id_e::REQUEST_SERVICE_ID: + { + protocol::request_service_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + its_client = its_command.get_client(); + auto its_requests = its_command.get_services(); + + std::set its_allowed_requests; + for (const auto &r : its_requests) { + if (VSOMEIP_SEC_OK == security::is_client_allowed_to_request( + _sec_client, r.service_, r.instance_)) { + host_->request_service(its_client, + r.service_, r.instance_, r.major_, r.minor_); + its_allowed_requests.insert(r); } + } + if (configuration_->is_security_enabled()) { + handle_credentials(its_client, its_allowed_requests); + } + handle_requests(its_client, its_allowed_requests); + } else + VSOMEIP_ERROR << __func__ << ": request service deserialization failed (" + << std::dec << static_cast(its_error) << ")"; - std::set its_eventgroups; - reliability_type_e its_reliability = reliability_type_e::RT_UNKNOWN; - - std::memcpy(&its_service, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_notifier, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_notifier)); - std::memcpy(&its_event_type, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(its_event_type)); - std::memcpy(&is_provided, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7], - sizeof(is_provided)); - std::memcpy(&its_reliability, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 8], - sizeof(its_reliability)); - if (is_provided - && !configuration_->is_offered_remote(its_service, - its_instance)) { - break; + break; + } + + case protocol::id_e::RELEASE_SERVICE_ID: + { + protocol::release_service_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + host_->release_service(its_command.get_client(), + its_command.get_service(), its_command.get_instance()); + } else + VSOMEIP_ERROR << __func__ << ": release service deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::REGISTER_EVENT_ID: + { + protocol::register_events_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + its_client = its_command.get_client(); + for(std::size_t i = 0; i < its_command.get_num_registrations(); i++) { + protocol::register_event register_event; + if (!its_command.get_registration_at(i, register_event)) { + continue; } - for (std::size_t i = 9; i+1 < its_size; i++) { - std::memcpy(&its_eventgroup, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + i], - sizeof(its_eventgroup)); - its_eventgroups.insert(its_eventgroup); + + its_service = register_event.get_service(); + its_instance = register_event.get_instance(); + + if (register_event.is_provided() + && !configuration_->is_offered_remote(its_service, its_instance)) { + continue; } + host_->register_shadow_event(its_client, its_service, its_instance, - its_notifier, its_eventgroups, its_event_type, - its_reliability, - is_provided); + register_event.get_event(), register_event.get_eventgroups(), + register_event.get_event_type(), register_event.get_reliability(), + register_event.is_provided(), register_event.is_cyclic()); + VSOMEIP_INFO << "REGISTER EVENT(" << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_notifier - << ":is_provider=" << is_provided << ":reliability=" - << (std::uint32_t)(its_reliability) << "]"; - break; + << std::hex << std::setw(4) << std::setfill('0') << its_instance + << ":eventtype=" << std::dec << (int)register_event.get_event_type() + << ":is_provided=" << std::boolalpha << register_event.is_provided() + << ":reliable=" << std::dec << (int)register_event.get_reliability() << "]"; } - case VSOMEIP_UNREGISTER_EVENT: - if (_size != VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a UNREGISTER_EVENT command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_service)); - std::memcpy(&its_instance, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], - sizeof(its_instance)); - std::memcpy(&its_notifier, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], - sizeof(its_notifier)); - std::memcpy(&is_provided, - &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], - sizeof(is_provided)); - if (is_provided - && !configuration_->is_offered_remote(its_service, - its_instance)) { - break; - } - host_->unregister_shadow_event(its_client, its_service, its_instance, - its_notifier, is_provided); - VSOMEIP_INFO << "UNREGISTER EVENT(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << "): [" - << std::hex << std::setw(4) << std::setfill('0') << its_service << "." - << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_notifier - << ":is_provider=" << is_provided << "]"; - break; - case VSOMEIP_REGISTERED_ACK: - if (_size != VSOMEIP_REGISTERED_ACK_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a REGISTERED_ACK command with wrong size ~> skip!"; - break; - } - VSOMEIP_INFO << "REGISTERED_ACK(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << ")"; - break; - case VSOMEIP_OFFERED_SERVICES_REQUEST: { - if (_size != VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a VSOMEIP_OFFERED_SERVICES_REQUEST command with wrong size ~> skip!"; - break; - } - std::memcpy(&its_offer_type, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(its_offer_type)); + } else + VSOMEIP_ERROR << __func__ << ": register event deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } - std::lock_guard its_guard(routing_info_mutex_); - create_offered_services_info(its_client); - - for (const auto& found_client : routing_info_) { - // skip services which are offered on remote hosts - if (found_client.first != VSOMEIP_ROUTING_CLIENT) { - for (const auto &its_service : found_client.second.second) { - for (const auto &its_instance : its_service.second) { - uint16_t its_reliable_port = configuration_->get_reliable_port(its_service.first, - its_instance.first); - uint16_t its_unreliable_port = configuration_->get_unreliable_port( - its_service.first, its_instance.first); - - if (its_offer_type == offer_type_e::OT_LOCAL) { - if (its_reliable_port == ILLEGAL_PORT - && its_unreliable_port == ILLEGAL_PORT) { - insert_offered_services_info(its_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - its_service.first, its_instance.first, - its_instance.second.first, its_instance.second.second); - } - } - else if (its_offer_type == offer_type_e::OT_REMOTE) { - if (its_reliable_port != ILLEGAL_PORT - || its_unreliable_port != ILLEGAL_PORT) { - insert_offered_services_info(its_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - its_service.first, its_instance.first, - its_instance.second.first, its_instance.second.second); - } - } else if (its_offer_type == offer_type_e::OT_ALL) { - insert_offered_services_info(its_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - its_service.first, its_instance.first, - its_instance.second.first, its_instance.second.second); - } - } - } - } - } - send_offered_services_info(its_client); - break; - } - case VSOMEIP_RESEND_PROVIDED_EVENTS: { - if (_size != VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE) { - VSOMEIP_WARNING << "Received a RESEND_PROVIDED_EVENTS command with wrong size ~> skip!"; - break; - } - pending_remote_offer_id_t its_pending_remote_offer_id(0); - std::memcpy(&its_pending_remote_offer_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_remote_offer_id_t)); - host_->on_resend_provided_events_response(its_pending_remote_offer_id); - VSOMEIP_INFO << "RESEND_PROVIDED_EVENTS(" - << std::hex << std::setw(4) << std::setfill('0') << its_client << ")"; - break; - } - case VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE: { - if (_size != VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_UPDATE_SECURITY_POLICY_RESPONSE " - << "command with wrong size ~> skip!"; - break; - } - pending_security_update_id_t its_pending_security_update_id(0); - std::memcpy(&its_pending_security_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_security_update_id_t)); + case protocol::id_e::UNREGISTER_EVENT_ID: + { + protocol::unregister_event_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + host_->unregister_shadow_event(its_command.get_client(), + its_command.get_service(), its_command.get_instance(), + its_command.get_event(), its_command.is_provided()); + + VSOMEIP_INFO << "UNREGISTER EVENT(" + << std::hex << std::setw(4) << std::setfill('0') << its_command.get_client() << "): [" + << std::hex << std::setw(4) << std::setfill('0') << its_command.get_service() << "." + << std::hex << std::setw(4) << std::setfill('0') << its_command.get_instance() << "." + << std::hex << std::setw(4) << std::setfill('0') << its_command.get_event() + << ":is_provider=" << std::boolalpha << its_command.is_provided() << "]"; + } else + VSOMEIP_ERROR << __func__ << ": unregister event deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } - on_security_update_response(its_pending_security_update_id ,its_client); - break; - } - case VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE: { - if (_size != VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE_COMMAND_SIZE) { - VSOMEIP_WARNING << "vSomeIP Security: Received a VSOMEIP_REMOVE_SECURITY_POLICY_RESPONSE " - << "command with wrong size ~> skip!"; - break; - } - pending_security_update_id_t its_pending_security_update_id(0); - std::memcpy(&its_pending_security_update_id, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], - sizeof(pending_security_update_id_t)); + case protocol::id_e::REGISTERED_ACK_ID: + { + protocol::registered_ack_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + VSOMEIP_INFO << "REGISTERED_ACK(" + << std::hex << std::setw(4) << std::setfill('0') + << its_command.get_client() << ")"; + } else + VSOMEIP_ERROR << __func__ << ": registered ack deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } - on_security_update_response(its_pending_security_update_id ,its_client); - break; - } - } + case protocol::id_e::OFFERED_SERVICES_REQUEST_ID: + { + protocol::offered_services_request_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + + on_offered_service_request(its_command.get_client(), its_command.get_offer_type()); + } else + VSOMEIP_ERROR << __func__ << ": offer service request deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::RESEND_PROVIDED_EVENTS_ID: + { + protocol::resend_provided_events_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + host_->on_resend_provided_events_response(its_command.get_remote_offer_id()); + VSOMEIP_INFO << "RESEND_PROVIDED_EVENTS(" + << std::hex << std::setw(4) << std::setfill('0') << its_client << ")"; + } else + VSOMEIP_ERROR << __func__ << ": resend provided events deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } +#ifndef VSOMEIP_DISABLE_SECURITY + case protocol::id_e::UPDATE_SECURITY_POLICY_RESPONSE_ID: + { + protocol::update_security_policy_response_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + on_security_update_response(its_command.get_update_id(), its_client); + } else + VSOMEIP_ERROR << __func__ << ": update security policy deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; + } + + case protocol::id_e::REMOVE_SECURITY_POLICY_RESPONSE_ID: + { + protocol::remove_security_policy_response_command its_command; + its_command.deserialize(its_buffer, its_error); + if (its_error == protocol::error_e::ERROR_OK) { + on_security_update_response(its_command.get_update_id(), its_client); + } else + VSOMEIP_ERROR << __func__ << ": update security policy deserialization failed (" + << std::dec << static_cast(its_error) << ")"; + break; } +#endif // !VSOMEIP_DISABLE_SECURITY + default: + VSOMEIP_WARNING << __func__ << ": Received an unhandled command (" + << std::dec << static_cast(its_id) << ")"; } } +void routing_manager_stub::add_known_client(client_t _client, const std::string &_client_host) { + host_->add_known_client(_client, _client_host); +} + void routing_manager_stub::on_register_application(client_t _client) { + auto endpoint = host_->find_local(_client); if (endpoint) { VSOMEIP_WARNING << "Reregistering application: " << std::hex << _client @@ -794,15 +825,21 @@ void routing_manager_stub::on_register_application(client_t _client) { std::lock_guard its_lock(routing_info_mutex_); routing_info_[_client].first = 0; } +#ifndef VSOMEIP_DISABLE_SECURITY + if (configuration_->is_local_routing()) { + vsomeip_sec_client_t its_sec_client; + std::set > its_policies; + + policy_manager_impl::get()->get_client_to_sec_client_mapping(_client, its_sec_client); + if (its_sec_client.client_type == VSOMEIP_CLIENT_UDS) { + get_requester_policies(its_sec_client.client.uds_client.user, + its_sec_client.client.uds_client.group, its_policies); + } - std::pair its_uid_gid; - std::set > its_policies; - - security::get()->get_client_to_uid_gid_mapping(_client, its_uid_gid); - get_requester_policies(its_uid_gid.first, its_uid_gid.second, its_policies); - - if (!its_policies.empty()) - send_requester_policies({ _client }, its_policies); + if (!its_policies.empty()) + send_requester_policies({ _client }, its_policies); + } +#endif // !VSOMEIP_DISABLE_SECURITY } } @@ -827,15 +864,59 @@ void routing_manager_stub::on_deregister_application(client_t _client) { routing_info_.erase(_client); } for (const auto &s : services_to_report) { - host_->on_availability(std::get<0>(s), std::get<1>(s), false, + host_->on_availability(std::get<0>(s), std::get<1>(s), + availability_state_e::AS_UNAVAILABLE, std::get<2>(s), std::get<3>(s)); host_->on_stop_offer_service(_client, std::get<0>(s), std::get<1>(s), std::get<2>(s), std::get<3>(s)); } } +void +routing_manager_stub::on_offered_service_request(client_t _client, + offer_type_e _offer_type) { + + protocol::offered_services_response_command its_command; + its_command.set_client(_client); + + for (const auto& found_client : routing_info_) { + // skip services which are offered on remote hosts + if (found_client.first != VSOMEIP_ROUTING_CLIENT) { + for (const auto &s : found_client.second.second) { + for (const auto &i : s.second) { + uint16_t its_reliable_port + = configuration_->get_reliable_port(s.first, i.first); + uint16_t its_unreliable_port + = configuration_->get_unreliable_port(s.first, i.first); + bool has_port = (its_reliable_port != ILLEGAL_PORT + || its_unreliable_port != ILLEGAL_PORT); + + if (_offer_type == offer_type_e::OT_ALL + || (_offer_type == offer_type_e::OT_LOCAL && !has_port) + || (_offer_type == offer_type_e::OT_REMOTE && has_port)) { + + protocol::service its_service(s.first, i.first, + i.second.first, i.second.second); + its_command.add_service(its_service); + } + } + } + } + } + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::shared_ptr its_endpoint = host_->find_local(_client); + if (its_endpoint) + its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size())); + } +} + void routing_manager_stub::client_registration_func(void) { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) { std::stringstream s; s << std::hex << std::setw(4) << std::setfill('0') @@ -845,9 +926,9 @@ void routing_manager_stub::client_registration_func(void) { #endif std::unique_lock its_lock(client_registration_mutex_); while (client_registration_running_) { - while (!pending_client_registrations_.size() && client_registration_running_) { - client_registration_condition_.wait(its_lock); - } + client_registration_condition_.wait(its_lock, [this] { + return pending_client_registrations_.size() || !client_registration_running_; + }); std::map> its_registrations( pending_client_registrations_); @@ -867,44 +948,53 @@ void routing_manager_stub::client_registration_func(void) { // endpoint error to avoid writing in an already closed socket if (b != registration_type_e::DEREGISTER_ON_ERROR) { std::lock_guard its_guard(routing_info_mutex_); - create_client_routing_info(r.first); - insert_client_routing_info(r.first, - b == registration_type_e::REGISTER ? - routing_info_entry_e::RIE_ADD_CLIENT : - routing_info_entry_e::RIE_DEL_CLIENT, - r.first); - // distribute updated security config to new clients + add_connection(r.first, r.first); + protocol::routing_info_entry its_entry; + its_entry.set_client(r.first); if (b == registration_type_e::REGISTER) { + boost::asio::ip::address its_address; + port_t its_port; + + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_CLIENT); + if (host_->get_guest(r.first, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } +#ifndef VSOMEIP_DISABLE_SECURITY + // distribute updated security config to new clients send_cached_security_policies(r.first); +#endif // !VSOMEIP_DISABLE_SECURITY + } else { + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_DELETE_CLIENT); } - send_client_routing_info(r.first); + send_client_routing_info(r.first, its_entry); } if (b != registration_type_e::REGISTER) { { std::lock_guard its_guard(routing_info_mutex_); - auto its_connection = connection_matrix_.find(r.first); - if (its_connection != connection_matrix_.end()) { - for (auto its_client : its_connection->second) { + auto find_connections = connection_matrix_.find(r.first); + if (find_connections != connection_matrix_.end()) { + for (auto its_client : find_connections->second) { if (its_client != r.first && its_client != VSOMEIP_ROUTING_CLIENT && its_client != get_client()) { - create_client_routing_info(its_client); - insert_client_routing_info(its_client, - routing_info_entry_e::RIE_DEL_CLIENT, r.first); - send_client_routing_info(its_client); + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_DELETE_CLIENT); + its_entry.set_client(r.first); + send_client_routing_info(its_client, its_entry); } } - connection_matrix_.erase(r.first); + remove_source(r.first); } - for (const auto& its_client : connection_matrix_) { - connection_matrix_[its_client.first].erase(r.first); + for (const auto &its_connections : connection_matrix_) { + remove_connection(its_connections.first, r.first); } service_requests_.erase(r.first); } // Don't remove client ID to UID maping as same client // could have passed its credentials again host_->remove_local(r.first, false); - utility::release_client_id(r.first); + utility::release_client_id(configuration_->get_network(), r.first); } } } @@ -913,9 +1003,75 @@ void routing_manager_stub::client_registration_func(void) { } void routing_manager_stub::init_routing_endpoint() { - endpoint_ = host_->get_endpoint_manager()->create_local_server( - &is_socket_activated_, shared_from_this()); + +#if defined(__linux__) || defined(ANDROID) + if (configuration_->is_local_routing()) { +#else + { +#endif // __linux__ || ANDROID + bool is_successful = host_->get_endpoint_manager()->create_routing_root( + root_, is_socket_activated_, shared_from_this()); + + if (!is_successful) { + VSOMEIP_WARNING << "Routing root creating (partially) failed. Please check your configuration."; + } +#if defined(__linux__) || defined(ANDROID) + } else { + auto its_host_address = configuration_->get_routing_host_address(); + local_link_connector_ = std::make_shared( + io_, its_host_address, boost::asio::ip::address(), false); // routing host doesn't need link up + if (local_link_connector_) { + local_link_connector_->register_net_if_changes_handler( + std::bind(&routing_manager_stub::on_net_state_change, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + } +#endif // __linux__ || ANDROID + } +} + +#if defined(__linux__) || defined(ANDROID) +void +routing_manager_stub::on_net_state_change( + bool _is_interface, const std::string &_name, bool _is_available) { + + VSOMEIP_INFO << __func__ + << "("<< std::hex << std::this_thread::get_id() << "): " + << std::boolalpha << _is_interface << " " + << _name << " " + << std::boolalpha << _is_available; + + if (_is_interface) { + if (_is_available) { + if (!is_local_link_available_) { + is_local_link_available_ = true; + if (!root_) + (void)host_->get_endpoint_manager()->create_routing_root( + root_, is_socket_activated_, shared_from_this()); + if (root_) { + VSOMEIP_INFO << __func__ + << ": Starting routing root."; + root_->start(); + } else + VSOMEIP_WARNING << "Routing root creating (partially) failed. " + "Please check your configuration."; + } + } else { + if (is_local_link_available_) { + + VSOMEIP_INFO << __func__ + << ": Stopping routing root."; + root_->stop(); + + routing_info_.clear(); + host_->clear_local_services(); + + is_local_link_available_ = false; + } + } + } } +#endif // __linux__ || ANDROID void routing_manager_stub::on_offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) { @@ -925,11 +1081,11 @@ void routing_manager_stub::on_offer_service(client_t _client, std::lock_guard its_guard(routing_info_mutex_); routing_info_[_client].second[_service][_instance] = std::make_pair(_major, _minor); - if (security::get()->is_enabled()) { + if (configuration_->is_security_enabled()) { distribute_credentials(_client, _service, _instance); } inform_requesters(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, true); + protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE, true); } void routing_manager_stub::on_stop_offer_service(client_t _client, @@ -947,102 +1103,29 @@ void routing_manager_stub::on_stop_offer_service(client_t _client, if (0 == found_service->second.size()) { found_client->second.second.erase(_service); } - inform_provider(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE); inform_requesters(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE, false); + protocol::routing_info_entry_type_e::RIE_DELETE_SERVICE_INSTANCE, false); } else if( _major == DEFAULT_MAJOR && _minor == DEFAULT_MINOR) { found_service->second.erase(_instance); if (0 == found_service->second.size()) { found_client->second.second.erase(_service); } - inform_provider(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE); inform_requesters(_client, _service, _instance, _major, _minor, - routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE, false); + protocol::routing_info_entry_type_e::RIE_DELETE_SERVICE_INSTANCE, false); } } } } } -void routing_manager_stub::create_client_routing_info(const client_t _target) { - std::vector its_command; - its_command.push_back(VSOMEIP_ROUTING_INFO); - - // Sender client - client_t client = get_client(); - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast(&client)[i]); - } - - // Overall size placeholder - byte_t size_placeholder = 0x0; - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(size_placeholder); - } - - client_routing_info_[_target] = its_command; -} - -void routing_manager_stub::create_client_credentials_info(const client_t _target) { - std::vector its_command; - its_command.push_back(VSOMEIP_UPDATE_SECURITY_CREDENTIALS); - - // Sender client - client_t client = get_client(); - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast(&client)[i]); - } - - // Overall size placeholder - byte_t size_placeholder = 0x0; - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(size_placeholder); - } - - client_credentials_info_[_target] = its_command; -} - -void routing_manager_stub::insert_client_credentials_info(client_t _target, std::set> _credentials) { - if (client_credentials_info_.find(_target) == client_credentials_info_.end()) { - return; - } - - auto its_command = client_credentials_info_[_target]; - - // insert uid / gid credential pairs - for (auto its_credentials : _credentials) { - //uid - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back( - reinterpret_cast(&std::get<0>(its_credentials))[i]); - } - //gid - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back( - reinterpret_cast(&std::get<1>(its_credentials))[i]); - } - } - - client_credentials_info_[_target] = its_command; -} - -void routing_manager_stub::send_client_credentials_info(const client_t _target) { - if (client_credentials_info_.find(_target) == client_credentials_info_.end()) { - return; - } +void routing_manager_stub::send_client_credentials(const client_t _target, + std::set> &_credentials) { std::shared_ptr its_endpoint = host_->find_local(_target); if (its_endpoint) { - auto its_command = client_credentials_info_[_target]; - - // File overall size - std::size_t its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS; - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t)); - its_size += VSOMEIP_COMMAND_PAYLOAD_POS; + protocol::update_security_credentials_command its_command; + its_command.set_client(_target); + its_command.set_credentials(_credentials); #if 0 std::stringstream msg; @@ -1052,235 +1135,66 @@ void routing_manager_stub::send_client_credentials_info(const client_t _target) VSOMEIP_INFO << msg.str(); #endif - // Send routing info or error! - if(its_command.size() <= max_local_message_size_ - || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) { - its_endpoint->send(&its_command[0], uint32_t(its_size)); - } else { - VSOMEIP_ERROR << "Credentials info exceeds maximum message size: Can't send!"; - } - - client_credentials_info_.erase(_target); - } else { - VSOMEIP_ERROR << "Send credentials info to client 0x" << std::hex << _target - << " failed: No valid endpoint!"; - } -} - -void routing_manager_stub::create_offered_services_info(const client_t _target) { - std::vector its_command; - its_command.push_back(VSOMEIP_OFFERED_SERVICES_RESPONSE); - - // Sender client - client_t client = get_client(); - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast(&client)[i]); - } - - // Overall size placeholder - byte_t size_placeholder = 0x0; - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(size_placeholder); - } - - offered_services_info_[_target] = its_command; -} - - -void routing_manager_stub::send_client_routing_info(const client_t _target) { - if (client_routing_info_.find(_target) == client_routing_info_.end()) { - return; - } - std::shared_ptr its_endpoint = host_->find_local(_target); - if (its_endpoint) { - auto its_command = client_routing_info_[_target]; - - // File overall size - std::size_t its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS; - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t)); - its_size += VSOMEIP_COMMAND_PAYLOAD_POS; - -#if 0 - std::stringstream msg; - msg << "rms::send_routing_info to (" << std::hex << _target << "): "; - for (uint32_t i = 0; i < its_size; ++i) - msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - - // Send routing info or error! - if(its_command.size() <= max_local_message_size_ - || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) { - its_endpoint->send(&its_command[0], uint32_t(its_size)); - } else { - VSOMEIP_ERROR << "Routing info exceeds maximum message size: Can't send!"; - } - - client_routing_info_.erase(_target); - } else { - VSOMEIP_ERROR << "Send routing info to client 0x" << std::hex << _target - << " failed: No valid endpoint!"; - } -} - - -void routing_manager_stub::send_offered_services_info(const client_t _target) { - if (offered_services_info_.find(_target) == offered_services_info_.end()) { - return; - } - std::shared_ptr its_endpoint = host_->find_local(_target); - if (its_endpoint) { - auto its_command = offered_services_info_[_target]; - - // File overall size - std::size_t its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS; - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t)); - its_size += VSOMEIP_COMMAND_PAYLOAD_POS; - -#if 0 - std::stringstream msg; - msg << "rms::send_offered_services_info to (" << std::hex << _target << "): "; - for (uint32_t i = 0; i < its_size; ++i) - msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " "; - VSOMEIP_INFO << msg.str(); -#endif - - // Send routing info or error! - if(its_command.size() <= max_local_message_size_ - || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) { - its_endpoint->send(&its_command[0], uint32_t(its_size)); - } else { - VSOMEIP_ERROR << "Offered services info exceeds maximum message size: Can't send!"; - } - - offered_services_info_.erase(_target); - } else { - VSOMEIP_ERROR << "Send offered services info to client 0x" << std::hex << _target - << " failed: No valid endpoint!"; - } + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + if(its_buffer.size() <= max_local_message_size_ + || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) { + its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": Credentials info exceeds maximum message size: Can't send!"; + + } else + VSOMEIP_ERROR << __func__ + << ": update security credentials command serialization failed (" + << static_cast(its_error) + << ")"; + } else + VSOMEIP_ERROR << __func__ + << ": Sending credentials to client [" + << std::hex << std::setw(4) << std::setfill('0') + << _target + << "] failed"; } -void routing_manager_stub::insert_client_routing_info(client_t _target, - routing_info_entry_e _entry, - client_t _client, service_t _service, - instance_t _instance, - major_version_t _major, - minor_version_t _minor) { - - if (client_routing_info_.find(_target) == client_routing_info_.end()) { - return; - } - - connection_matrix_[_target].insert(_client); - - auto its_command = client_routing_info_[_target]; - - // Routing Info State Change - for (uint32_t i = 0; i < sizeof(routing_info_entry_e); ++i) { - its_command.push_back( - reinterpret_cast(&_entry)[i]); - } - - std::size_t its_size_pos = its_command.size(); - std::size_t its_entry_size = its_command.size(); - - // Client size placeholder - byte_t placeholder = 0x0; - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(placeholder); - } - // Client - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast(&_client)[i]); - } - - if (_entry == routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE || - _entry == routing_info_entry_e::RIE_DEL_SERVICE_INSTANCE) { - //Service - uint32_t its_service_entry_size = uint32_t(sizeof(service_t) - + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)); - for (uint32_t i = 0; i < sizeof(its_service_entry_size); ++i) { - its_command.push_back( - reinterpret_cast(&its_service_entry_size)[i]); - } - for (uint32_t i = 0; i < sizeof(service_t); ++i) { - its_command.push_back( - reinterpret_cast(&_service)[i]); - } - // Instance - for (uint32_t i = 0; i < sizeof(instance_t); ++i) { - its_command.push_back( - reinterpret_cast(&_instance)[i]); - } - // Major version - for (uint32_t i = 0; i < sizeof(major_version_t); ++i) { - its_command.push_back( - reinterpret_cast(&_major)[i]); - } - // Minor version - for (uint32_t i = 0; i < sizeof(minor_version_t); ++i) { - its_command.push_back( - reinterpret_cast(&_minor)[i]); - } - } - - // File client size - its_entry_size = its_command.size() - its_entry_size - uint32_t(sizeof(uint32_t)); - std::memcpy(&its_command[its_size_pos], &its_entry_size, sizeof(uint32_t)); +void routing_manager_stub::send_client_routing_info(const client_t _target, + protocol::routing_info_entry &_entry) { - client_routing_info_[_target] = its_command; + std::vector its_entries; + its_entries.emplace_back(_entry); + send_client_routing_info(_target, std::move(its_entries)); } -void routing_manager_stub::insert_offered_services_info(client_t _target, - routing_info_entry_e _entry, - service_t _service, - instance_t _instance, - major_version_t _major, - minor_version_t _minor) { +void routing_manager_stub::send_client_routing_info(const client_t _target, + std::vector &&_entries) { - if (offered_services_info_.find(_target) == offered_services_info_.end()) { - return; - } + auto its_target_endpoint = host_->find_local(_target); + if (its_target_endpoint) { - auto its_command = offered_services_info_[_target]; + protocol::routing_info_command its_command; + its_command.set_client(get_client()); + its_command.set_entries(std::move(_entries)); - // Routing Info State Change - for (uint32_t i = 0; i < sizeof(routing_info_entry_e); ++i) { - its_command.push_back( - reinterpret_cast(&_entry)[i]); - } + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); - // entry size - uint32_t its_service_entry_size = uint32_t(sizeof(service_t) - + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)); - for (uint32_t i = 0; i < sizeof(its_service_entry_size); ++i) { - its_command.push_back( - reinterpret_cast(&its_service_entry_size)[i]); - } - //Service - for (uint32_t i = 0; i < sizeof(service_t); ++i) { - its_command.push_back( - reinterpret_cast(&_service)[i]); - } - // Instance - for (uint32_t i = 0; i < sizeof(instance_t); ++i) { - its_command.push_back( - reinterpret_cast(&_instance)[i]); - } - // Major version - for (uint32_t i = 0; i < sizeof(major_version_t); ++i) { - its_command.push_back( - reinterpret_cast(&_major)[i]); - } - // Minor version - for (uint32_t i = 0; i < sizeof(minor_version_t); ++i) { - its_command.push_back( - reinterpret_cast(&_minor)[i]); - } - - offered_services_info_[_target] = its_command; + if (its_error == protocol::error_e::ERROR_OK) { + its_target_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": routing info command serialization failed (" + << static_cast(its_error) + << ")"; + } else + VSOMEIP_ERROR << __func__ + << ": Sending routing info to client [" + << std::hex << std::setw(4) << std::setfill('0') + << _target + << "] failed"; } void routing_manager_stub::distribute_credentials(client_t _hoster, service_t _service, instance_t _instance) { @@ -1298,38 +1212,30 @@ void routing_manager_stub::distribute_credentials(client_t _hoster, service_t _s } // search for UID / GID linked with the client ID that offers the requested services - std::pair its_uid_gid; - if (security::get()->get_client_to_uid_gid_mapping(_hoster, its_uid_gid)) { + vsomeip_sec_client_t its_sec_client; + if (policy_manager_impl::get()->get_client_to_sec_client_mapping(_hoster, its_sec_client)) { + std::pair its_uid_gid; + its_uid_gid.first = its_sec_client.client.uds_client.user; + its_uid_gid.second = its_sec_client.client.uds_client.group; its_credentials.insert(its_uid_gid); for (auto its_requesting_client : its_requesting_clients) { - std::pair its_requester_uid_gid; - if (security::get()->get_client_to_uid_gid_mapping(its_requesting_client, its_requester_uid_gid)) { - if (its_uid_gid != its_requester_uid_gid) { - create_client_credentials_info(its_requesting_client); - insert_client_credentials_info(its_requesting_client, its_credentials); - send_client_credentials_info(its_requesting_client); - } + vsomeip_sec_client_t its_requester_sec_client; + if (policy_manager_impl::get()->get_client_to_sec_client_mapping( + its_requesting_client, its_requester_sec_client)) { + if (!utility::compare(its_sec_client, its_requester_sec_client)) + send_client_credentials(its_requesting_client, its_credentials); } } } } -void routing_manager_stub::inform_provider(client_t _hoster, service_t _service, +void routing_manager_stub::inform_requesters(client_t _hoster, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, - routing_info_entry_e _entry) { + protocol::routing_info_entry_type_e _type, bool _inform_service) { - if (_hoster != VSOMEIP_ROUTING_CLIENT - && _hoster != host_->get_client()) { - create_client_routing_info(_hoster); - insert_client_routing_info(_hoster, _entry, _hoster, - _service, _instance, _major, _minor); - send_client_routing_info(_hoster); - } -}; + boost::asio::ip::address its_address; + port_t its_port; -void routing_manager_stub::inform_requesters(client_t _hoster, service_t _service, - instance_t _instance, major_version_t _major, minor_version_t _minor, - routing_info_entry_e _entry, bool _inform_service) { for (auto its_client : service_requests_) { auto its_service = its_client.second.find(_service); if (its_service != its_client.second.end()) { @@ -1338,31 +1244,39 @@ void routing_manager_stub::inform_requesters(client_t _hoster, service_t _servic if (_inform_service) { if (_hoster != VSOMEIP_ROUTING_CLIENT && _hoster != host_->get_client()) { - if (!is_already_connected(_hoster, its_client.first)) { - create_client_routing_info(_hoster); - insert_client_routing_info(_hoster, - routing_info_entry_e::RIE_ADD_CLIENT, - its_client.first); - send_client_routing_info(_hoster); + if (!is_connected(_hoster, its_client.first)) { + add_connection(_hoster, its_client.first); + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_CLIENT); + its_entry.set_client(its_client.first); + if (host_->get_guest(its_client.first, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } + send_client_routing_info(_hoster, its_entry); } } } if (its_client.first != VSOMEIP_ROUTING_CLIENT && its_client.first != get_client()) { - create_client_routing_info(its_client.first); - insert_client_routing_info(its_client.first, _entry, _hoster, - _service, _instance, _major, _minor); - send_client_routing_info(its_client.first); + add_connection(its_client.first, _hoster); + protocol::routing_info_entry its_entry; + its_entry.set_type(_type); + its_entry.set_client(_hoster); + if ((_type == protocol::routing_info_entry_type_e::RIE_ADD_CLIENT + || _type == protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE) + && host_->get_guest(_hoster, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } + its_entry.add_service({ _service, _instance, _major, _minor} ); + send_client_routing_info(its_client.first, its_entry); } } } } } -bool routing_manager_stub::is_already_connected(client_t _source, client_t _sink) { - return connection_matrix_[_source].find(_sink) != connection_matrix_[_source].end(); -} - void routing_manager_stub::broadcast(const std::vector &_command) const { std::lock_guard its_guard(routing_info_mutex_); for (const auto& a : routing_info_) { @@ -1376,42 +1290,50 @@ void routing_manager_stub::broadcast(const std::vector &_command) const } } -bool routing_manager_stub::send_subscribe(const std::shared_ptr& _target, - client_t _client, service_t _service, instance_t _instance, +bool routing_manager_stub::send_subscribe( + const std::shared_ptr& _target, client_t _client, + service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, - event_t _event, remote_subscription_id_t _id) { + event_t _event, const std::shared_ptr &_filter, + remote_subscription_id_t _id) { + + bool has_sent(false); + if (_target) { - byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6] = _major; - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], &_id, - sizeof(_id)); - - return _target->send(its_command, sizeof(its_command)); + + protocol::subscribe_command its_command; + its_command.set_client(_client); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_major(_major); + its_command.set_event(_event); + its_command.set_filter(_filter); + its_command.set_pending_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + has_sent = _target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": subscribe command serialization failed (" + << std::dec << int(its_error) << ")"; + } else { - VSOMEIP_WARNING << __func__ << " Couldn't send subscription to local client [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << _event << "]" - << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') - << _client; - return false; + VSOMEIP_WARNING << __func__ + << " Couldn't send subscription to local client [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << _event << "]" + << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') + << _client; } + + return (has_sent); } bool routing_manager_stub::send_unsubscribe( @@ -1419,37 +1341,41 @@ bool routing_manager_stub::send_unsubscribe( client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, remote_subscription_id_t _id) { + + bool has_sent(false); + if (_target) { - byte_t its_command[VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNSUBSCRIBE; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_id, - sizeof(_id)); - - return _target->send(its_command, sizeof(its_command)); + + protocol::unsubscribe_command its_command; + its_command.set_client(_client); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_event(_event); + its_command.set_pending_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + has_sent = _target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": unsubscribe command serialization failed (" + << std::dec << int(its_error) << ")"; } else { - VSOMEIP_WARNING << __func__ << " Couldn't send unsubscription to local client [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << _event << "]" - << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') - << _client; - return false; + VSOMEIP_WARNING << __func__ + << " Couldn't send unsubscription to local client [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << _event << "]" + << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') + << _client; } + + return (has_sent); } bool routing_manager_stub::send_expired_subscription( @@ -1457,100 +1383,94 @@ bool routing_manager_stub::send_expired_subscription( client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, remote_subscription_id_t _id) { + + bool has_sent(false); + if (_target) { - byte_t its_command[VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_EXPIRED_SUBSCRIPTION_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_EXPIRED_SUBSCRIPTION; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_id, - sizeof(_id)); - - return _target->send(its_command, sizeof(its_command)); + + protocol::expire_command its_command; + its_command.set_client(_client); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_event(_event); + its_command.set_pending_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + has_sent = _target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": unsubscribe command serialization failed (" + << std::dec << int(its_error) << ")"; } else { - VSOMEIP_WARNING << __func__ << " Couldn't send expired subscription to local client [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." - << std::hex << std::setw(4) << std::setfill('0') << _event << "]" - << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') - << _client; - return false; + VSOMEIP_WARNING << __func__ + << " Couldn't send expired subscription to local client [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "." + << std::hex << std::setw(4) << std::setfill('0') << _event << "]" + << " subscriber: "<< std::hex << std::setw(4) << std::setfill('0') + << _client; } + + return (has_sent); } void routing_manager_stub::send_subscribe_ack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { - std::shared_ptr its_endpoint = host_->find_local(_client); - if (its_endpoint) { - byte_t its_command[VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_ACK_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - client_t this_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_ACK; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &this_client, - sizeof(this_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], - &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID)); - - its_endpoint->send(&its_command[0], sizeof(its_command)); + std::shared_ptr its_target = host_->find_local(_client); + if (its_target) { + + protocol::subscribe_ack_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_subscriber(_client); + its_command.set_event(_event); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + (void)its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": subscribe ack command serialization failed (" + << std::dec << int(its_error) << ")"; } } void routing_manager_stub::send_subscribe_nack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { - std::shared_ptr its_endpoint = host_->find_local(_client); - if (its_endpoint) { - byte_t its_command[VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE]; - uint32_t its_size = VSOMEIP_SUBSCRIBE_NACK_COMMAND_SIZE - - VSOMEIP_COMMAND_HEADER_SIZE; - - client_t this_client = get_client(); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SUBSCRIBE_NACK; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &this_client, - sizeof(this_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service, - sizeof(_service)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance, - sizeof(_instance)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_eventgroup, - sizeof(_eventgroup)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6], &_client, - sizeof(_client)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_event, - sizeof(_event)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 10], - &PENDING_SUBSCRIPTION_ID, sizeof(PENDING_SUBSCRIPTION_ID)); - - its_endpoint->send(&its_command[0], sizeof(its_command)); + std::shared_ptr its_target = host_->find_local(_client); + if (its_target) { + + protocol::subscribe_nack_command its_command; + its_command.set_client(get_client()); + its_command.set_service(_service); + its_command.set_instance(_instance); + its_command.set_eventgroup(_eventgroup); + its_command.set_subscriber(_client); + its_command.set_event(_event); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + (void)its_target->send(&its_buffer[0], uint32_t(its_buffer.size())); + } else + VSOMEIP_ERROR << __func__ + << ": subscribe ack command serialization failed (" + << std::dec << int(its_error) << ")"; } } @@ -1576,7 +1496,19 @@ bool routing_manager_stub::contained_in_routing_info( // Watchdog void routing_manager_stub::broadcast_ping() const { - broadcast(its_ping_); + + protocol::ping_command its_command; + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) + broadcast(its_buffer); + else + VSOMEIP_ERROR << __func__ + << ": ping command serialization failed (" + << std::dec << int(its_error) << ")"; } void routing_manager_stub::on_pong(client_t _client) { @@ -1656,8 +1588,8 @@ void routing_manager_stub::create_local_receiver() { if (local_receiver_) { return; } -#ifndef _WIN32 - else if (!security::get()->check_credentials(get_client(), getuid(), getgid())) { +#if defined(__linux__) || defined(ANDROID) + else if (!policy_manager_impl::get()->check_credentials(get_client(), host_->get_sec_client())) { VSOMEIP_ERROR << "vSomeIP Security: Client 0x" << std::hex << get_client() << " : routing_manager_stub::create_local_receiver: isn't allowed" << " to create a server endpoint due to credential check failed!"; @@ -1666,56 +1598,71 @@ void routing_manager_stub::create_local_receiver() { #endif local_receiver_ = std::static_pointer_cast( host_->get_endpoint_manager())->create_local_server(shared_from_this()); - local_receiver_->start(); + + if (local_receiver_) + local_receiver_->start(); } bool routing_manager_stub::send_ping(client_t _client) { - std::shared_ptr its_endpoint = host_->find_local(_client); - if (!its_endpoint) { - return false; - } - { + bool has_sent(false); + + std::shared_ptr its_endpoint = host_->find_local(_client); + if (its_endpoint) { std::lock_guard its_lock(pinged_clients_mutex_); if (pinged_clients_.find(_client) != pinged_clients_.end()) { // client was already pinged: don't ping again and wait for answer // or timeout of previous ping. - return true; - } - - boost::system::error_code ec; - pinged_clients_timer_.cancel(ec); - if (ec) { - VSOMEIP_ERROR << "routing_manager_stub::send_ping cancellation of " - "timer failed: " << ec.message(); - } - const std::chrono::steady_clock::time_point now( - std::chrono::steady_clock::now()); + has_sent = true; + } else { + boost::system::error_code ec; + pinged_clients_timer_.cancel(ec); + if (ec) { + VSOMEIP_ERROR << "routing_manager_stub::send_ping cancellation of " + "timer failed: " << ec.message(); + } + const std::chrono::steady_clock::time_point now( + std::chrono::steady_clock::now()); - std::chrono::milliseconds next_timeout(configured_watchdog_timeout_); - for (const auto &tp : pinged_clients_) { - const std::chrono::milliseconds its_clients_timeout = - std::chrono::duration_cast( - now - tp.second); - if (next_timeout > its_clients_timeout) { - next_timeout = its_clients_timeout; + std::chrono::milliseconds next_timeout(configured_watchdog_timeout_); + for (const auto &tp : pinged_clients_) { + const std::chrono::milliseconds its_clients_timeout = + std::chrono::duration_cast( + now - tp.second); + if (next_timeout > its_clients_timeout) { + next_timeout = its_clients_timeout; + } } - } - pinged_clients_[_client] = now; + pinged_clients_[_client] = now; - ec.clear(); - pinged_clients_timer_.expires_from_now(next_timeout, ec); - if (ec) { - VSOMEIP_ERROR<< "routing_manager_stub::send_ping setting " - "expiry time of timer failed: " << ec.message(); + ec.clear(); + pinged_clients_timer_.expires_from_now(next_timeout, ec); + if (ec) { + VSOMEIP_ERROR << "routing_manager_stub::send_ping setting " + "expiry time of timer failed: " << ec.message(); + } + pinged_clients_timer_.async_wait( + std::bind(&routing_manager_stub::on_ping_timer_expired, this, + std::placeholders::_1)); + + protocol::ping_command its_command; + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) + has_sent = its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size())); + else + VSOMEIP_ERROR << __func__ + << ": ping command serialization failed (" + << std::dec << int(its_error) << ")"; } - pinged_clients_timer_.async_wait( - std::bind(&routing_manager_stub::on_ping_timer_expired, this, - std::placeholders::_1)); - return its_endpoint->send(&its_ping_[0], uint32_t(its_ping_.size())); } + + return (has_sent); } void routing_manager_stub::on_ping_timer_expired( @@ -1821,19 +1768,33 @@ bool routing_manager_stub::is_registered(client_t _client) const { } void routing_manager_stub::update_registration(client_t _client, - registration_type_e _type) { + registration_type_e _type, + const boost::asio::ip::address &_address, port_t _port) { + + std::stringstream its_client; + its_client << std::hex << std::setw(4) << std::setfill('0') + << _client; + + if (_port > 0 && _port < ILLEGAL_PORT) { + its_client << " @ " << _address.to_string() << ":" << std::dec << _port; + } VSOMEIP_INFO << "Application/Client " - << std::hex << std::setw(4) << std::setfill('0') << _client + << its_client.str() << " is " << (_type == registration_type_e::REGISTER ? "registering." : "deregistering."); if (_type != registration_type_e::REGISTER) { - security::get()->remove_client_to_uid_gid_mapping(_client); + policy_manager_impl::get()->remove_client_to_sec_client_mapping(_client); + } else { + if (_port > 0 && _port < ILLEGAL_PORT) + host_->add_guest(_client, _address, _port); } if (_type == registration_type_e::DEREGISTER) { + host_->remove_guest(_client); + // If we receive a DEREGISTER client command // the endpoint error handler is not longer needed // as the client is going down anyways. @@ -1868,15 +1829,15 @@ client_t routing_manager_stub::get_client() const { return host_->get_client(); } -void routing_manager_stub::handle_credentials(const client_t _client, std::set& _requests) { +void routing_manager_stub::handle_credentials(const client_t _client, std::set &_requests) { if (!_requests.size()) { return; } std::lock_guard its_guard(routing_info_mutex_); std::set> its_credentials; - std::pair its_requester_uid_gid; - if (security::get()->get_client_to_uid_gid_mapping(_client, its_requester_uid_gid)) { + vsomeip_sec_client_t its_requester_sec_client; + if (policy_manager_impl::get()->get_client_to_sec_client_mapping(_client, its_requester_sec_client)) { // determine credentials of offering clients using current routing info std::set its_offering_clients; @@ -1891,65 +1852,79 @@ void routing_manager_stub::handle_credentials(const client_t _client, std::set its_uid_gid; - if (security::get()->get_client_to_uid_gid_mapping(its_offering_client, its_uid_gid)) { - if (its_uid_gid != its_requester_uid_gid) { - its_credentials.insert(std::make_pair(std::get<0>(its_uid_gid), std::get<1>(its_uid_gid))); + vsomeip_sec_client_t its_sec_client; + if (policy_manager_impl::get()->get_client_to_sec_client_mapping(its_offering_client, its_sec_client)) { + if (its_sec_client.client_type == VSOMEIP_CLIENT_UDS + && !utility::compare(its_sec_client, its_requester_sec_client)) { + + its_credentials.insert(std::make_pair( + its_sec_client.client.uds_client.user, its_sec_client.client.uds_client.group)); } } } // send credentials to clients - if (!its_credentials.empty()) { - create_client_credentials_info(_client); - insert_client_credentials_info(_client, its_credentials); - send_client_credentials_info(_client); - } + if (!its_credentials.empty()) + send_client_credentials(_client, its_credentials); } } -void routing_manager_stub::handle_requests(const client_t _client, std::set& _requests) { - if (!_requests.size()) { +void routing_manager_stub::handle_requests(const client_t _client, std::set &_requests) { + + if (_requests.empty()) return; - } - bool service_available(false); + + boost::asio::ip::address its_address; + port_t its_port; + + std::vector its_entries; std::lock_guard its_guard(routing_info_mutex_); - create_client_routing_info(_client); + for (auto request : _requests) { service_requests_[_client][request.service_][request.instance_] - = std::make_pair(request.major_, request.minor_); + = std::make_pair(request.major_, request.minor_); if (request.instance_ == ANY_INSTANCE) { std::set its_clients = host_->find_local_clients(request.service_, request.instance_); - // insert VSOMEIP_ROUTING_CLIENT to check wether service is remotely offered + // insert VSOMEIP_ROUTING_CLIENT to check whether service is remotely offered its_clients.insert(VSOMEIP_ROUTING_CLIENT); for (const client_t c : its_clients) { if (c != VSOMEIP_ROUTING_CLIENT && c != host_->get_client()) { - if (!is_already_connected(c, _client)) { + if (!is_connected(c, _client)) { + add_connection(c, _client); + + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_CLIENT); + its_entry.set_client(_client); + if (host_->get_guest(_client, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } if (_client == c) { - service_available = true; - insert_client_routing_info(c, - routing_info_entry_e::RIE_ADD_CLIENT, _client); + its_entries.emplace_back(its_entry); } else { - create_client_routing_info(c); - insert_client_routing_info(c, - routing_info_entry_e::RIE_ADD_CLIENT, _client); - send_client_routing_info(c); + send_client_routing_info(c, its_entry); } } } - if (_client != VSOMEIP_ROUTING_CLIENT && - _client != host_->get_client()) { + if (_client != VSOMEIP_ROUTING_CLIENT && _client != host_->get_client()) { const auto found_client = routing_info_.find(c); if (found_client != routing_info_.end()) { const auto found_service = found_client->second.second.find(request.service_); if (found_service != found_client->second.second.end()) { for (auto instance : found_service->second) { - service_available = true; - insert_client_routing_info(_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - c, request.service_, instance.first, - instance.second.first, instance.second.second); + add_connection(_client, c); + + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE); + its_entry.set_client(c); + if (host_->get_guest(c, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } + its_entry.add_service({ request.service_, instance.first, + instance.second.first, instance.second.second }); + its_entries.emplace_back(its_entry); } } } @@ -1963,38 +1938,46 @@ void routing_manager_stub::handle_requests(const client_t _client, std::setsecond.second.end()) { const auto found_instance = found_service->second.find(request.instance_); if (found_instance != found_service->second.end()) { - if (c != VSOMEIP_ROUTING_CLIENT && - c != host_->get_client()) { - if (!is_already_connected(c, _client)) { + if (c != VSOMEIP_ROUTING_CLIENT && c != host_->get_client()) { + if (!is_connected(c, _client)) { + add_connection(c, _client); + + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_CLIENT); + its_entry.set_client(_client); + if (host_->get_guest(_client, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } if (_client == c) { - service_available = true; - insert_client_routing_info(c, - routing_info_entry_e::RIE_ADD_CLIENT, _client); + its_entries.emplace_back(its_entry); } else { - create_client_routing_info(c); - insert_client_routing_info(c, - routing_info_entry_e::RIE_ADD_CLIENT, _client); - send_client_routing_info(c); + send_client_routing_info(c, its_entry); } } } - if (_client != VSOMEIP_ROUTING_CLIENT && - _client != host_->get_client()) { - service_available = true; - insert_client_routing_info(_client, - routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, - c, request.service_, request.instance_, - found_instance->second.first, - found_instance->second.second); + if (_client != VSOMEIP_ROUTING_CLIENT && _client != host_->get_client()) { + add_connection(_client, c); + + protocol::routing_info_entry its_entry; + its_entry.set_type(protocol::routing_info_entry_type_e::RIE_ADD_SERVICE_INSTANCE); + its_entry.set_client(c); + if (host_->get_guest(c, its_address, its_port)) { + its_entry.set_address(its_address); + its_entry.set_port(its_port); + } + its_entry.add_service({ request.service_, request.instance_, + found_instance->second.first, found_instance->second.second }); + its_entries.emplace_back(its_entry); } } } } } } - if (service_available) { - send_client_routing_info(_client); - } + + if (!its_entries.empty()) + send_client_routing_info(_client, std::move(its_entries)); } void routing_manager_stub::on_client_id_timer_expired(boost::system::error_code const &_error) { @@ -2029,34 +2012,37 @@ void routing_manager_stub::print_endpoint_status() const { if (local_receiver_) { local_receiver_->print_status(); } - if (endpoint_) { - endpoint_->print_status(); + if (root_) { + root_->print_status(); } } -bool routing_manager_stub::send_provided_event_resend_request(client_t _client, - pending_remote_offer_id_t _id) { +bool routing_manager_stub::send_provided_event_resend_request( + client_t _client, pending_remote_offer_id_t _id) { + std::shared_ptr its_endpoint = host_->find_local(_client); if (its_endpoint) { - byte_t its_command[VSOMEIP_RESEND_PROVIDED_EVENTS_COMMAND_SIZE]; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_RESEND_PROVIDED_EVENTS; - const client_t routing_client(VSOMEIP_ROUTING_CLIENT); - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &routing_client, - sizeof(routing_client)); - std::uint32_t its_size = sizeof(pending_remote_offer_id_t); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_id, - sizeof(pending_remote_offer_id_t)); - return its_endpoint->send(its_command, sizeof(its_command)); + + protocol::resend_provided_events_command its_command; + its_command.set_client(VSOMEIP_ROUTING_CLIENT); + its_command.set_remote_offer_id(_id); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) + return (its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size()))); } else { VSOMEIP_WARNING << __func__ << " Couldn't send provided event resend " "request to local client: 0x" << std::hex << std::setw(4) << std::setfill('0') << _client; - return false; } + + return (false); } +#ifndef VSOMEIP_DISABLE_SECURITY bool routing_manager_stub::is_policy_cached(uint32_t _uid) { { std::lock_guard its_lock(updated_security_policies_mutex_); @@ -2089,11 +2075,16 @@ void routing_manager_stub::policy_cache_remove(uint32_t _uid) { bool routing_manager_stub::send_update_security_policy_request(client_t _client, pending_security_update_id_t _update_id, uint32_t _uid, const std::shared_ptr& _payload) { (void)_uid; + std::shared_ptr its_endpoint = host_->find_local(_client); if (its_endpoint) { std::vector its_command; // command - its_command.push_back(VSOMEIP_UPDATE_SECURITY_POLICY); + its_command.push_back(byte_t(protocol::id_e::UPDATE_SECURITY_POLICY_ID)); + + // version + its_command.push_back(0x00); + its_command.push_back(0x00); // client ID for (uint32_t i = 0; i < sizeof(client_t); ++i) { @@ -2123,89 +2114,74 @@ bool routing_manager_stub::send_update_security_policy_request(client_t _client, } bool routing_manager_stub::send_cached_security_policies(client_t _client) { - std::vector its_command; - std::size_t its_size(0); - std::lock_guard its_lock(updated_security_policies_mutex_); - uint32_t its_policy_count = uint32_t(updated_security_policies_.size()); + std::shared_ptr its_endpoint = host_->find_local(_client); + if (its_endpoint) { - if (!its_policy_count) { - return true; - } - VSOMEIP_INFO << __func__ << " Distributing [" - << std::dec << its_policy_count - << "] security policy updates to registering client: " - << std::hex << _client; + std::lock_guard its_lock(updated_security_policies_mutex_); + if (!updated_security_policies_.empty()) { - // command - its_command.push_back(VSOMEIP_DISTRIBUTE_SECURITY_POLICIES); + VSOMEIP_INFO << __func__ << " Distributing [" + << std::dec << updated_security_policies_.size() + << "] security policy updates to registering client: " + << std::hex << _client; - // client ID - client_t its_client = get_client(); - for (uint32_t i = 0; i < sizeof(client_t); ++i) { - its_command.push_back( - reinterpret_cast(&its_client)[i]); - } + protocol::distribute_security_policies_command its_command; + its_command.set_client(get_client()); + its_command.set_payloads(updated_security_policies_); - //overall size (placeholder - for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { - its_command.push_back(0x00); - } + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); - // number of policies contained in message - for (uint32_t i = 0; i < sizeof(its_policy_count); ++i) { - its_command.push_back( - reinterpret_cast(&its_policy_count)[i]); - } + if (its_error == protocol::error_e::ERROR_OK) + return its_endpoint->send(its_buffer.data(), uint32_t(its_buffer.size())); - for (const auto& its_uid_gid : updated_security_policies_) { - // policy payload length including gid and uid - std::uint32_t its_length = uint32_t(its_uid_gid.second->get_length()); - for (uint32_t i = 0; i < sizeof(its_length); ++i) { - its_command.push_back( - reinterpret_cast(&its_length)[i]); + VSOMEIP_ERROR << __func__ + << ": serializing distribute security policies (" + << static_cast(its_error) + << ")"; } - // payload - its_command.insert(its_command.end(), its_uid_gid.second->get_data(), - its_uid_gid.second->get_data() + its_uid_gid.second->get_length()); - } - // File overall size - its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS; - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t)); + } else + VSOMEIP_WARNING << __func__ + << ": could not send cached security policies to registering client: 0x" + << std::hex << std::setw(4) << std::setfill('0') << _client; + + return (false); +} + +bool routing_manager_stub::send_remove_security_policy_request( + client_t _client, pending_security_update_id_t _update_id, + uint32_t _uid, uint32_t _gid) { + + protocol::remove_security_policy_command its_command; + its_command.set_client(_client); + its_command.set_update_id(_update_id); + its_command.set_uid(_uid); + its_command.set_gid(_gid); + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); + + if (its_error == protocol::error_e::ERROR_OK) { + std::shared_ptr its_endpoint = host_->find_local(_client); + if (its_endpoint) + return (its_endpoint->send(&its_buffer[0], uint32_t(its_buffer.size()))); + else + VSOMEIP_ERROR << __func__ + << ": cannot find local client endpoint for client " + << std::hex << std::setw(4) << std::setfill('0') + << _client; + } else + VSOMEIP_ERROR << __func__ + << ": remove security policy command serialization failed (" + << std::dec << static_cast(its_error) + << ")"; - std::shared_ptr its_endpoint = host_->find_local(_client); - if (its_endpoint) { - return its_endpoint->send(its_command.data(), uint32_t(its_command.size())); - } else { - VSOMEIP_WARNING << __func__ << " Couldn't send cached security policies " - " to registering client: 0x" - << std::hex << std::setw(4) << std::setfill('0') << _client; - return false; - } -} + return (false); -bool routing_manager_stub::send_remove_security_policy_request( client_t _client, pending_security_update_id_t _update_id, - uint32_t _uid, uint32_t _gid) { - std::shared_ptr its_endpoint = host_->find_local(_client); - if (its_endpoint) { - byte_t its_command[VSOMEIP_REMOVE_SECURITY_POLICY_COMMAND_SIZE]; - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REMOVE_SECURITY_POLICY; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(client_t)); - std::uint32_t its_size = sizeof(_update_id) + sizeof(_uid) + sizeof(_gid); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, - sizeof(its_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_update_id, - sizeof(uint32_t)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_uid, - sizeof(uint32_t)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 8], &_gid, - sizeof(uint32_t)); - return its_endpoint->send(its_command, sizeof(its_command)); - } else { - return false; - } } bool @@ -2219,7 +2195,7 @@ routing_manager_stub::add_requester_policies(uid_t _uid, gid_t _gid, if (found_gid != found_uid->second.end()) { found_gid->second.insert(_policies.begin(), _policies.end()); } else { - found_uid->second.insert(std::make_pair(_gid, _policies)); + found_uid->second[_gid] = _policies; } } else { requester_policies_[_uid][_gid] = _policies; @@ -2228,7 +2204,7 @@ routing_manager_stub::add_requester_policies(uid_t _uid, gid_t _gid, // Check whether clients with uid/gid are already registered. // If yes, update their policy std::unordered_set its_clients; - security::get()->get_clients(_uid, _gid, its_clients); + policy_manager_impl::get()->get_clients(_uid, _gid, its_clients); if (!its_clients.empty()) return send_requester_policies(its_clients, _policies); @@ -2263,7 +2239,7 @@ routing_manager_stub::get_requester_policies(uid_t _uid, gid_t _gid, void routing_manager_stub::add_pending_security_update_handler( - pending_security_update_id_t _id, security_update_handler_t _handler) { + pending_security_update_id_t _id, const security_update_handler_t &_handler) { std::lock_guard its_lock(security_update_handlers_mutex_); security_update_handlers_[_id] = _handler; @@ -2304,7 +2280,13 @@ routing_manager_stub::send_requester_policies(const std::unordered_set std::vector its_policy_data; if (p->serialize(its_policy_data)) { std::vector its_message; - its_message.push_back(VSOMEIP_UPDATE_SECURITY_POLICY_INT); + its_message.push_back(byte_t(protocol::id_e::UPDATE_SECURITY_POLICY_INT_ID)); + + // version + its_message.push_back(0); + its_message.push_back(0); + + // client identifier its_message.push_back(0); its_message.push_back(0); @@ -2322,7 +2304,7 @@ routing_manager_stub::send_requester_policies(const std::unordered_set its_message.insert(its_message.end(), its_policy_data.begin(), its_policy_data.end()); - for (const auto& c : _clients) { + for (const auto c : _clients) { std::shared_ptr its_endpoint = host_->find_local(c); if (its_endpoint) its_endpoint->send(&its_message[0], static_cast(its_message.size())); @@ -2401,11 +2383,11 @@ bool routing_manager_stub::update_security_policy_configuration( policy_cache_add(_uid, _payload); // update security policy from configuration - security::get()->update_security_policy(_uid, _gid, _policy); + policy_manager_impl::get()->update_security_policy(_uid, _gid, _policy); // Build requester policies for the services offered by the new policy std::set > its_requesters; - security::get()->get_requester_policies(_policy, its_requesters); + policy_manager_impl::get()->get_requester_policies(_policy, its_requesters); // and add them to the requester policy cache add_requester_policies(_uid, _gid, its_requesters); @@ -2464,7 +2446,7 @@ bool routing_manager_stub::remove_security_policy_configuration( // remove security policy from configuration (only if there was a updateACL call before) if (is_policy_cached(_uid)) { - if (!security::get()->remove_security_policy(_uid, _gid)) { + if (!policy_manager_impl::get()->remove_security_policy(_uid, _gid)) { _handler(security_update_state_e::SU_UNKNOWN_USER_ID); ret = false; } else { @@ -2611,13 +2593,33 @@ void routing_manager_stub::on_security_update_response( } } } +#endif // !VSOMEIP_DISABLE_SECURITY void routing_manager_stub::send_suspend() const { - static const std::vector its_suspend( - { VSOMEIP_SUSPEND, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); + protocol::suspend_command its_command; + + std::vector its_buffer; + protocol::error_e its_error; + its_command.serialize(its_buffer, its_error); - broadcast(its_suspend); + if (its_error == protocol::error_e::ERROR_OK) + broadcast(its_buffer); + else + VSOMEIP_ERROR << __func__ + << ": suspend command serialization failed (" + << std::dec << int(its_error) << ")"; +} + +void +routing_manager_stub::remove_subscriptions(port_t _local_port, + const boost::asio::ip::address &_remote_address, + port_t _remote_port) { + + (void)_local_port; + (void)_remote_address; + (void)_remote_port; + // dummy method to implement routing_host interface } } // namespace vsomeip_v3 diff --git a/implementation/routing/src/serviceinfo.cpp b/implementation/routing/src/serviceinfo.cpp index 324fcd7..fcdcbd8 100644 --- a/implementation/routing/src/serviceinfo.cpp +++ b/implementation/routing/src/serviceinfo.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,8 +10,7 @@ namespace vsomeip_v3 { serviceinfo::serviceinfo(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, ttl_t _ttl, bool _is_local) - : group_(0), - service_(_service), + : service_(_service), instance_(_instance), major_(_major), minor_(_minor), @@ -26,7 +25,6 @@ serviceinfo::serviceinfo(service_t _service, instance_t _instance, } serviceinfo::serviceinfo(const serviceinfo& _other) : - group_(_other.group_), service_(_other.service_), instance_(_other.instance_), major_(_other.major_), @@ -42,14 +40,6 @@ serviceinfo::serviceinfo(const serviceinfo& _other) : serviceinfo::~serviceinfo() { } -servicegroup * serviceinfo::get_group() const { - return group_; -} - -void serviceinfo::set_group(servicegroup *_group) { - group_ = _group; -} - service_t serviceinfo::get_service() const { return service_; } diff --git a/implementation/runtime/include/application_impl.hpp b/implementation/runtime/include/application_impl.hpp index 37df949..5dc9ef8 100644 --- a/implementation/runtime/include/application_impl.hpp +++ b/implementation/runtime/include/application_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -40,7 +41,8 @@ class application_impl: public application, public routing_manager_host, public std::enable_shared_from_this { public: - VSOMEIP_EXPORT application_impl(const std::string &_name); + VSOMEIP_EXPORT application_impl(const std::string &_name, + const std::string &_path); VSOMEIP_EXPORT ~application_impl(); VSOMEIP_EXPORT bool init(); @@ -84,6 +86,9 @@ public: VSOMEIP_EXPORT void subscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, event_t _event); + VSOMEIP_EXPORT void subscribe_with_debounce(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const debounce_filter_t &_filter); VSOMEIP_EXPORT void unsubscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup); @@ -103,23 +108,28 @@ public: event_t _event, std::shared_ptr _payload, client_t _client, bool _force) const; - VSOMEIP_EXPORT void register_state_handler(state_handler_t _handler); + VSOMEIP_EXPORT void register_state_handler(const state_handler_t &_handler); VSOMEIP_EXPORT void unregister_state_handler(); VSOMEIP_EXPORT void register_message_handler(service_t _service, - instance_t _instance, method_t _method, message_handler_t _handler); + instance_t _instance, method_t _method, const message_handler_t &_handler); VSOMEIP_EXPORT void unregister_message_handler(service_t _service, instance_t _instance, method_t _method); VSOMEIP_EXPORT void register_availability_handler(service_t _service, - instance_t _instance, availability_handler_t _handler, + instance_t _instance, const availability_handler_t &_handler, + major_version_t _major, minor_version_t _minor); + VSOMEIP_EXPORT void register_availability_handler(service_t _service, + instance_t _instance, const availability_state_handler_t &_handler, major_version_t _major, minor_version_t _minor); VSOMEIP_EXPORT void unregister_availability_handler(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor); VSOMEIP_EXPORT void register_subscription_handler(service_t _service, - instance_t _instance, eventgroup_t _eventgroup, subscription_handler_t _handler); + instance_t _instance, eventgroup_t _eventgroup, const subscription_handler_t &_handler); + VSOMEIP_EXPORT void register_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, const subscription_handler_ext_t &_handler); VSOMEIP_EXPORT void unregister_subscription_handler(service_t _service, instance_t _instance, eventgroup_t _eventgroup); @@ -129,19 +139,20 @@ public: VSOMEIP_EXPORT const std::string & get_name() const; VSOMEIP_EXPORT client_t get_client() const; VSOMEIP_EXPORT void set_client(const client_t &_client); - VSOMEIP_EXPORT session_t get_session(); + VSOMEIP_EXPORT session_t get_session(bool _is_request); + VSOMEIP_EXPORT const vsomeip_sec_client_t *get_sec_client() const; VSOMEIP_EXPORT diagnosis_t get_diagnosis() const; VSOMEIP_EXPORT std::shared_ptr get_configuration() const; VSOMEIP_EXPORT std::shared_ptr get_public_configuration() const; - VSOMEIP_EXPORT boost::asio::io_service & get_io(); + VSOMEIP_EXPORT boost::asio::io_context &get_io(); VSOMEIP_EXPORT void on_state(state_type_e _state); VSOMEIP_EXPORT void on_availability(service_t _service, instance_t _instance, - bool _is_available, major_version_t _major, minor_version_t _minor); + availability_state_e _state, major_version_t _major, minor_version_t _minor); VSOMEIP_EXPORT void on_message(std::shared_ptr &&_message); VSOMEIP_EXPORT void on_subscription(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, client_t _client, uid_t _uid, gid_t _gid, bool _subscribed, - std::function _accepted_cb); + eventgroup_t _eventgroup, client_t _client, const vsomeip_sec_client_t *_sec_client, + const std::string &_env, bool _subscribed, const std::function &_accepted_cb); VSOMEIP_EXPORT void on_subscription_status(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, uint16_t _error); VSOMEIP_EXPORT void register_subscription_status_handler(service_t _service, @@ -161,14 +172,17 @@ public: VSOMEIP_EXPORT void clear_all_handler(); - VSOMEIP_EXPORT void get_offered_services_async(offer_type_e _offer_type, offered_services_handler_t _handler); + VSOMEIP_EXPORT void get_offered_services_async(offer_type_e _offer_type, const offered_services_handler_t &_handler); VSOMEIP_EXPORT void on_offered_services_info(std::vector> &_services); - VSOMEIP_EXPORT void set_watchdog_handler(watchdog_handler_t _handler, std::chrono::seconds _interval); + VSOMEIP_EXPORT void set_watchdog_handler(const watchdog_handler_t &_handler, std::chrono::seconds _interval); VSOMEIP_EXPORT void register_async_subscription_handler(service_t _service, - instance_t _instance, eventgroup_t _eventgroup, async_subscription_handler_t _handler); + instance_t _instance, eventgroup_t _eventgroup, const async_subscription_handler_t &_handler); + + VSOMEIP_EXPORT void register_async_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, const async_subscription_handler_ext_t &_handler); VSOMEIP_EXPORT void set_sd_acceptance_required(const remote_info_t& _remote, const std::string& _path, bool _enable); @@ -177,12 +191,12 @@ public: VSOMEIP_EXPORT sd_acceptance_map_type_t get_sd_acceptance_required(); - VSOMEIP_EXPORT void register_sd_acceptance_handler(sd_acceptance_handler_t _handler); + VSOMEIP_EXPORT void register_sd_acceptance_handler(const sd_acceptance_handler_t &_handler); - VSOMEIP_EXPORT void register_reboot_notification_handler(reboot_notification_handler_t _handler); + VSOMEIP_EXPORT void register_reboot_notification_handler(const reboot_notification_handler_t &_handler); - VSOMEIP_EXPORT void register_routing_ready_handler(routing_ready_handler_t _handler); - VSOMEIP_EXPORT void register_routing_state_handler(routing_state_handler_t _handler); + VSOMEIP_EXPORT void register_routing_ready_handler(const routing_ready_handler_t &_handler); + VSOMEIP_EXPORT void register_routing_state_handler(const routing_state_handler_t &_handler); VSOMEIP_EXPORT bool update_service_configuration(service_t _service, instance_t _instance, @@ -195,10 +209,22 @@ public: uint32_t _gid, std::shared_ptr _policy, std::shared_ptr _payload, - security_update_handler_t _handler); + const security_update_handler_t &_handler); VSOMEIP_EXPORT void remove_security_policy_configuration(uint32_t _uid, uint32_t _gid, - security_update_handler_t _handler); + const security_update_handler_t &_handler); + + VSOMEIP_EXPORT void register_message_acceptance_handler(const message_acceptance_handler_t &_handler); + + VSOMEIP_EXPORT std::map + get_additional_data(const std::string &_plugin_name); + + VSOMEIP_EXPORT void register_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + const subscription_handler_sec_t &_handler); + VSOMEIP_EXPORT void register_async_subscription_handler( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + async_subscription_handler_sec_t _handler); private: // @@ -217,7 +243,7 @@ private: struct sync_handler { - sync_handler(std::function _handler) : + sync_handler(const std::function &_handler) : handler_(_handler), service_id_(ANY_SERVICE), instance_id_(ANY_INSTANCE), @@ -247,7 +273,7 @@ private: }; struct message_handler { - message_handler(message_handler_t _handler) : + message_handler(const message_handler_t &_handler) : handler_(_handler) {} bool operator<(const message_handler& _other) const { @@ -260,14 +286,15 @@ private: // // Methods // - bool is_available_unlocked(service_t _service, instance_t _instance, + availability_state_e is_available_unlocked(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) const; - bool are_available_unlocked(available_t &_available, + availability_state_e are_available_unlocked(available_t &_available, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) const; - void do_register_availability_handler(service_t _service, - instance_t _instance, availability_handler_t _handler, + + void register_availability_handler_unlocked(service_t _service, + instance_t _instance, availability_state_handler_t _handler, major_version_t _major, minor_version_t _minor); @@ -303,6 +330,8 @@ private: void watchdog_cbk(boost::system::error_code const &_error); + bool is_local_endpoint(const boost::asio::ip::address &_unicast, port_t _port); + // // Attributes // @@ -315,11 +344,13 @@ private: bool is_initialized_; std::string name_; + + std::string path_; std::shared_ptr configuration_; - boost::asio::io_service io_; + boost::asio::io_context io_; std::set > io_threads_; - std::shared_ptr work_; + std::shared_ptr work_; // Proxy to or the Routing Manager itself std::shared_ptr routing_; @@ -344,19 +375,25 @@ private: mutable std::mutex members_mutex_; // Availability handlers - typedef std::map>> availability_major_minor_t; + using availability_major_minor_t = + std::map>>; std::map> availability_; - mutable std::recursive_mutex availability_mutex_; + mutable std::mutex availability_mutex_; // Availability - mutable available_t available_; + using available_instance_t = + std::map>>; + using available_ext_t = std::map; + mutable available_ext_t available_; // Subscription handlers std::map>>> subscription_; + std::pair > > > subscription_; mutable std::mutex subscription_mutex_; std::map, - subscription_state_e> subscription_state_; + std::map + > + > + > subscription_state_; std::mutex watchdog_timer_mutex_; boost::asio::steady_timer watchdog_timer_; @@ -432,12 +474,9 @@ private: std::map, std::deque > > availability_handlers_; - uid_t own_uid_; - gid_t own_gid_; + vsomeip_sec_client_t sec_client_; -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG bool has_session_handling_; -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG }; } // namespace vsomeip_v3 diff --git a/implementation/runtime/include/runtime_impl.hpp b/implementation/runtime/include/runtime_impl.hpp index ec49a42..b618ec4 100644 --- a/implementation/runtime/include/runtime_impl.hpp +++ b/implementation/runtime/include/runtime_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -24,6 +24,8 @@ public: std::shared_ptr create_application( const std::string &_name); + std::shared_ptr create_application( + const std::string &_name, const std::string &_path); std::shared_ptr create_message(bool _reliable) const; std::shared_ptr create_request(bool _reliable) const; diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp index 467bca2..e854958 100644 --- a/implementation/runtime/src/application_impl.cpp +++ b/implementation/runtime/src/application_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,9 +8,11 @@ #include #include +#include +#include #include -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #include #endif @@ -28,14 +30,14 @@ #include "../../configuration/include/configuration.hpp" #include "../../configuration/include/configuration_plugin.hpp" #endif // VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS +#include "../../endpoints/include/endpoint.hpp" #include "../../message/include/serializer.hpp" -#include "../../routing/include/routing_manager_impl.hpp" -#include "../../routing/include/routing_manager_proxy.hpp" -#include "../../utility/include/utility.hpp" -#include "../../tracing/include/connector_impl.hpp" #include "../../plugin/include/plugin_manager_impl.hpp" -#include "../../endpoints/include/endpoint.hpp" +#include "../../routing/include/routing_manager_impl.hpp" +#include "../../routing/include/routing_manager_client.hpp" #include "../../security/include/security.hpp" +#include "../../tracing/include/connector_impl.hpp" +#include "../../utility/include/utility.hpp" namespace vsomeip_v3 { @@ -46,12 +48,14 @@ configuration::~configuration() {} uint32_t application_impl::app_counter__ = 0; std::mutex application_impl::app_counter_mutex__; -application_impl::application_impl(const std::string &_name) +application_impl::application_impl(const std::string &_name, const std::string &_path) : runtime_(runtime::get()), client_(VSOMEIP_CLIENT_UNSET), session_(0), - is_initialized_(false), name_(_name), - work_(std::make_shared(io_)), + is_initialized_(false), + name_(_name), + path_(_path), + work_(std::make_shared(io_)), routing_(0), state_(state_type_e::ST_DEREGISTERED), security_mode_(security_mode_e::SM_OFF), @@ -67,17 +71,9 @@ application_impl::application_impl(const std::string &_name) is_routing_manager_host_(false), stopped_called_(false), watchdog_timer_(io_), - client_side_logging_(false) -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG - , has_session_handling_(true) -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG + client_side_logging_(false), + has_session_handling_(true) { - own_uid_ = ANY_UID; - own_gid_ = ANY_GID; -#ifndef _WIN32 - own_uid_ = getuid(); - own_gid_ = getgid(); -#endif } application_impl::~application_impl() { @@ -143,19 +139,19 @@ bool application_impl::init() { auto its_configuration_plugin = std::dynamic_pointer_cast(its_plugin); if (its_configuration_plugin) { - configuration_ = its_configuration_plugin->get_configuration(name_); + configuration_ = its_configuration_plugin->get_configuration(name_, path_); VSOMEIP_INFO << "Configuration module loaded."; } else { std::cerr << "Invalid configuration module!" << std::endl; std::exit(EXIT_FAILURE); } } else { - std::cerr << "Configuration module could not be loaded!" << std::endl; + std::cerr << "1 Configuration module could not be loaded!" << std::endl; std::exit(EXIT_FAILURE); } #else configuration_ = std::dynamic_pointer_cast( - std::make_shared()); + std::make_shared(configuration_path)); if (configuration_path.length()) { configuration_->set_configuration_path(configuration_path); } @@ -163,14 +159,31 @@ bool application_impl::init() { #endif // VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS } + if (configuration_->is_local_routing()) { + sec_client_.client_type = VSOMEIP_CLIENT_UDS; +#ifdef __unix__ + sec_client_.client.uds_client.user = getuid(); + sec_client_.client.uds_client.group = getgid(); +#else + sec_client_.client.uds_client.user = ANY_UID; + sec_client_.client.uds_client.group = ANY_GID; +#endif + } else { + sec_client_.client_type = VSOMEIP_CLIENT_TCP; + } + // Set security mode - auto its_security = security::get(); - if (its_security->is_enabled()) { - if (its_security->is_audit()) { + if (configuration_->is_security_enabled()) { + if (configuration_->is_security_audit()) { security_mode_ = security_mode_e::SM_AUDIT; } else { security_mode_ = security_mode_e::SM_ON; } + + if (security::load()) { + VSOMEIP_INFO << "Using external security implementation!"; + security::initialize(); + } } else { security_mode_ = security_mode_e::SM_OFF; } @@ -234,18 +247,16 @@ bool application_impl::init() { max_dispatchers_ = its_configuration->get_max_dispatchers(name_) + 1; max_dispatch_time_ = its_configuration->get_max_dispatch_time(name_); -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG has_session_handling_ = its_configuration->has_session_handling(name_); if (!has_session_handling_) VSOMEIP_INFO << "application: " << name_ << " has session handling switched off!"; -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG - std::string its_routing_host = its_configuration->get_routing_host(); + std::string its_routing_host = its_configuration->get_routing_host_name(); if (its_routing_host != "") { is_routing_manager_host_ = (its_routing_host == name_); if (is_routing_manager_host_ && - !utility::is_routing_manager(configuration_)) { + !utility::is_routing_manager(configuration_->get_network())) { #ifndef VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS VSOMEIP_ERROR << "application: " << name_ << " configured as " "routing but other routing manager present. Won't " @@ -257,7 +268,11 @@ bool application_impl::init() { #endif // VSOMEIP_ENABLE_MULTIPLE_ROUTING_MANAGERS } } else { - is_routing_manager_host_ = utility::is_routing_manager(configuration_); + auto its_routing_address = its_configuration->get_routing_host_address(); + auto its_routing_port = its_configuration->get_routing_host_port(); + if (its_routing_address.is_unspecified() + || is_local_endpoint(its_routing_address, its_routing_port)) + is_routing_manager_host_ = utility::is_routing_manager(configuration_->get_network()); } if (is_routing_manager_host_) { @@ -271,10 +286,9 @@ bool application_impl::init() { routing_ = std::make_shared(this); } else { VSOMEIP_INFO << "Instantiating routing manager [Proxy]."; - routing_ = std::make_shared(this, client_side_logging_, client_side_logging_filter_); + routing_ = std::make_shared(this, client_side_logging_, client_side_logging_filter_); } - routing_->set_client(client_); routing_->init(); #ifdef USE_DLT @@ -343,7 +357,7 @@ bool application_impl::init() { } void application_impl::start() { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) if (getpid() != static_cast(syscall(SYS_gettid))) { // only set threadname if calling thread isn't the main thread std::stringstream s; @@ -382,7 +396,7 @@ void application_impl::start() { VSOMEIP_INFO << "Starting vsomeip application \"" << name_ << "\" (" << std::hex << std::setw(4) << std::setfill('0') << client_ << ") using " << std::dec << io_thread_count << " threads" -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) << " I/O nice " << io_thread_nice_level #endif ; @@ -411,11 +425,11 @@ void application_impl::start() { << std::hex << std::setw(4) << std::setfill('0') << client_ << " (" << name_ << ") is: " << std::hex << std::this_thread::get_id() - #ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) << " TID: " << std::dec << static_cast(syscall(SYS_gettid)) - #endif +#endif ; - #ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) { std::stringstream s; s << std::hex << std::setw(4) << std::setfill('0') @@ -426,7 +440,7 @@ void application_impl::start() { if ((VSOMEIP_IO_THREAD_NICE_LEVEL != io_thread_nice_level) && (io_thread_nice_level != nice(io_thread_nice_level))) { VSOMEIP_WARNING << "nice(" << io_thread_nice_level << ") failed " << errno << " for " << std::this_thread::get_id(); } - #endif +#endif try { io_.run(); } catch (const std::exception &e) { @@ -458,11 +472,11 @@ void application_impl::start() { VSOMEIP_INFO << "io thread id from application: " << std::hex << std::setw(4) << std::setfill('0') << client_ << " (" << name_ << ") is: " << std::hex << std::this_thread::get_id() -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) << " TID: " << std::dec << static_cast(syscall(SYS_gettid)) #endif ; -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) if ((VSOMEIP_IO_THREAD_NICE_LEVEL != io_thread_nice_level) && (io_thread_nice_level != nice(io_thread_nice_level))) { VSOMEIP_WARNING << "nice(" << io_thread_nice_level << ") failed " << errno << " for " << std::this_thread::get_id(); } @@ -546,9 +560,7 @@ void application_impl::stop() { if (block) { std::unique_lock block_stop_lock(block_stop_mutex_); - while (!block_stopping_) { - block_stop_cv_.wait(block_stop_lock); - } + block_stop_cv_.wait(block_stop_lock, [this] { return block_stopping_; }); block_stopping_ = false; } } @@ -603,8 +615,9 @@ void application_impl::subscribe(service_t _service, instance_t _instance, } if (check_subscription_state(_service, _instance, _eventgroup, _event)) { - routing_->subscribe(client_, own_uid_, own_gid_, _service, _instance, _eventgroup, _major, - _event); + routing_->subscribe(client_, &sec_client_, + _service, _instance, _eventgroup, _major, + _event, nullptr); } } } @@ -613,45 +626,45 @@ void application_impl::unsubscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup) { remove_subscription(_service, _instance, _eventgroup, ANY_EVENT); if (routing_) - routing_->unsubscribe(client_, own_uid_, own_gid_, _service, _instance, _eventgroup, ANY_EVENT); + routing_->unsubscribe(client_, &sec_client_, _service, _instance, _eventgroup, ANY_EVENT); } void application_impl::unsubscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { remove_subscription(_service, _instance, _eventgroup, _event); if (routing_) - routing_->unsubscribe(client_, own_uid_, own_gid_, _service, _instance, _eventgroup, _event); + routing_->unsubscribe(client_, &sec_client_, _service, _instance, _eventgroup, _event); } bool application_impl::is_available( service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) const { - std::lock_guard its_lock(availability_mutex_); - return is_available_unlocked(_service, _instance, _major, _minor); + std::lock_guard its_lock(availability_mutex_); + return (is_available_unlocked(_service, _instance, _major, _minor) + == availability_state_e::AS_AVAILABLE); } -bool application_impl::is_available_unlocked( +availability_state_e +application_impl::is_available_unlocked( service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) const { - bool is_available(false); + availability_state_e its_state(availability_state_e::AS_UNKNOWN); - auto check_major_minor = [&](const std::map>::const_iterator &_found_instance) { + auto check_major_minor = [&](const available_instance_t::const_iterator &_found_instance) { auto found_major = _found_instance->second.find(_major); if (found_major != _found_instance->second.end()) { - if (_minor <= found_major->second || _minor == ANY_MINOR + if (_minor <= found_major->second.first || _minor == ANY_MINOR || _minor == DEFAULT_MINOR) { - is_available = true; + its_state = found_major->second.second; } } else if ((_major == DEFAULT_MAJOR || _major == ANY_MAJOR)) { for (const auto &found_major : _found_instance->second) { if (_minor == DEFAULT_MINOR || _minor == ANY_MINOR) { - is_available = true; + its_state = found_major.second.second; break; - } else if (_minor <= found_major.second) { - is_available = true; + } else if (_minor <= found_major.second.first) { + its_state = found_major.second.second; break; } } @@ -666,7 +679,7 @@ bool application_impl::is_available_unlocked( for (auto it = found_service->second.cbegin(); it != found_service->second.cend(); it++) { check_major_minor(it); - if (is_available) { + if (its_state != availability_state_e::AS_UNKNOWN) { break; } } @@ -676,49 +689,53 @@ bool application_impl::is_available_unlocked( auto found_instance = found_service.second.find(_instance); if (found_instance != found_service.second.end()) { check_major_minor(found_instance); - if (is_available) { + if (its_state != availability_state_e::AS_UNKNOWN) { break; } } else if (_instance == ANY_INSTANCE) { for (auto it = found_service.second.cbegin(); it != found_service.second.cend(); it++) { check_major_minor(it); - if (is_available) { + if (its_state != availability_state_e::AS_UNKNOWN) { break; } } } - if (is_available) { + if (its_state != availability_state_e::AS_UNKNOWN) { break; } } } - return is_available; + return (its_state); } bool application_impl::are_available( available_t &_available, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) const { - std::lock_guard its_lock(availability_mutex_); - return are_available_unlocked(_available, _service, _instance, _major, _minor); + std::lock_guard its_lock(availability_mutex_); + return (are_available_unlocked(_available, _service, _instance, _major, _minor) + == availability_state_e::AS_AVAILABLE); } -bool application_impl::are_available_unlocked(available_t &_available, - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor) const { +availability_state_e +application_impl::are_available_unlocked(available_t &_available, + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor) const { //find available services if(_service == ANY_SERVICE) { //add all available services for(auto its_available_services_it = available_.begin(); its_available_services_it != available_.end(); - ++its_available_services_it) + ++its_available_services_it) { _available[its_available_services_it->first]; + } } else { // check if specific service is available - if(available_.find(_service) != available_.end()) + if(available_.find(_service) != available_.end()) { _available[_service]; + } } //find available instances @@ -733,11 +750,13 @@ bool application_impl::are_available_unlocked(available_t &_available, //add all available instances for(auto its_available_instances_it = found_available_service->second.begin(); its_available_instances_it != found_available_service->second.end(); - ++its_available_instances_it) + ++its_available_instances_it) { _available[its_available_services_it->first][its_available_instances_it->first]; + } } else { - if(found_available_service->second.find(_instance) != found_available_service->second.end()) + if(found_available_service->second.find(_instance) != found_available_service->second.end()) { _available[its_available_services_it->first][_instance]; + } } } } @@ -761,11 +780,13 @@ bool application_impl::are_available_unlocked(available_t &_available, //add all major versions for(auto its_available_major_it = found_available_instance->second.begin(); its_available_major_it != found_available_instance->second.end(); - ++its_available_major_it) + ++its_available_major_it) { _available[its_available_services_it->first][its_available_instances_it->first][its_available_major_it->first]; + } } else { - if(found_available_instance->second.find(_major) != found_available_instance->second.end()) + if(found_available_instance->second.find(_major) != found_available_instance->second.end()) { _available[its_available_services_it->first][its_available_instances_it->first][_major]; + } } } } @@ -793,11 +814,13 @@ bool application_impl::are_available_unlocked(available_t &_available, ++its_available_major_it) { //get available major version auto found_available_major = found_available_instance->second.find(its_available_major_it->first); - if(found_available_major != found_available_instance->second.end()) { - if(_minor == ANY_MINOR || _minor == DEFAULT_MINOR - || _minor <= found_available_major->second) { + if (found_available_major != found_available_instance->second.end()) { + if ((_minor == ANY_MINOR || _minor == DEFAULT_MINOR + || _minor <= found_available_major->second.first) + && availability_state_e::AS_AVAILABLE == found_available_major->second.second) { //add minor version - _available[its_available_services_it->first][its_available_instances_it->first][its_available_major_it->first] = found_available_major->second; + _available[its_available_services_it->first][its_available_instances_it->first][its_available_major_it->first] + = found_available_major->second.first; found_minor = true; } } @@ -811,11 +834,12 @@ bool application_impl::are_available_unlocked(available_t &_available, its_available_services_it = _available.erase(its_available_services_it); } - if(_available.empty()) { + if (_available.empty()) { _available[_service][_instance][_major] = _minor ; - return false; + + return (availability_state_e::AS_UNAVAILABLE); } - return true; + return (availability_state_e::AS_AVAILABLE); } void application_impl::send(std::shared_ptr _message) { @@ -840,15 +864,16 @@ void application_impl::send(std::shared_ptr _message) { // in case of requests set the request-id (client-id|session-id) if (is_request) { _message->set_client(client_); - _message->set_session(get_session()); + _message->set_session(get_session(true)); } // Always increment the session-id - (void)routing_->send(client_, _message); + (void)routing_->send(client_, _message, false); } } void application_impl::notify(service_t _service, instance_t _instance, event_t _event, std::shared_ptr _payload, bool _force) const { + if (routing_) routing_->notify(_service, _instance, _event, _payload, _force); } @@ -866,7 +891,7 @@ void application_impl::notify_one(service_t _service, instance_t _instance, } } -void application_impl::register_state_handler(state_handler_t _handler) { +void application_impl::register_state_handler(const state_handler_t &_handler) { std::lock_guard its_lock(state_handler_mutex_); handler_ = _handler; } @@ -877,45 +902,62 @@ void application_impl::unregister_state_handler() { } void application_impl::register_availability_handler(service_t _service, - instance_t _instance, availability_handler_t _handler, + instance_t _instance, const availability_handler_t &_handler, major_version_t _major, minor_version_t _minor) { - std::lock_guard availability_lock(availability_mutex_); - if (state_ == state_type_e::ST_REGISTERED) { - do_register_availability_handler(_service, _instance, - _handler, _major, _minor); - } else { - availability_[_service][_instance][_major][_minor] = std::make_pair( - _handler, false); - } + + std::lock_guard availability_lock(availability_mutex_); + auto its_handler_ext = [_handler](service_t _service, instance_t _instance, + availability_state_e _state) { + _handler(_service, _instance, + (_state == availability_state_e::AS_AVAILABLE)); + }; + + register_availability_handler_unlocked(_service, _instance, + its_handler_ext, _major, _minor); } -void application_impl::do_register_availability_handler(service_t _service, - instance_t _instance, availability_handler_t _handler, +void application_impl::register_availability_handler(service_t _service, + instance_t _instance, const availability_state_handler_t &_handler, major_version_t _major, minor_version_t _minor) { - available_t available; - bool are_available = are_available_unlocked(available, _service, _instance, _major, _minor); - availability_[_service][_instance][_major][_minor] = std::make_pair( - _handler, true); - std::lock_guard handlers_lock(handlers_mutex_); + std::lock_guard availability_lock(availability_mutex_); + register_availability_handler_unlocked(_service, _instance, + _handler, _major, _minor); +} - std::shared_ptr its_sync_handler - = std::make_shared([_handler, are_available, available]() { - for(const auto& available_services_it : available) - for(const auto& available_instances_it : available_services_it.second) - _handler(available_services_it.first, available_instances_it.first, are_available); - }); - its_sync_handler->handler_type_ = handler_type_e::AVAILABILITY; - its_sync_handler->service_id_ = _service; - its_sync_handler->instance_id_ = _instance; - handlers_.push_back(its_sync_handler); +void application_impl::register_availability_handler_unlocked(service_t _service, + instance_t _instance, availability_state_handler_t _handler, + major_version_t _major, minor_version_t _minor) { + + if (state_ == state_type_e::ST_REGISTERED) { + available_t its_available; + auto are_available = are_available_unlocked(its_available, _service, _instance, _major, _minor); + availability_[_service][_instance][_major][_minor] + = std::make_pair(_handler, true); + + std::lock_guard handlers_lock(handlers_mutex_); + + std::shared_ptr its_sync_handler + = std::make_shared([_handler, are_available, its_available]() { + for(const auto& available_services_it : its_available) + for(const auto& available_instances_it : available_services_it.second) + _handler(available_services_it.first, available_instances_it.first, are_available); + }); + its_sync_handler->handler_type_ = handler_type_e::AVAILABILITY; + its_sync_handler->service_id_ = _service; + its_sync_handler->instance_id_ = _instance; + handlers_.push_back(its_sync_handler); - dispatcher_condition_.notify_one(); + dispatcher_condition_.notify_one(); + } else { + availability_[_service][_instance][_major][_minor] + = std::make_pair(_handler, false); + } } void application_impl::unregister_availability_handler(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor) { - std::lock_guard its_lock(availability_mutex_); + std::lock_guard its_lock(availability_mutex_); auto found_service = availability_.find(_service); if (found_service != availability_.end()) { auto found_instance = found_service->second.find(_instance); @@ -941,11 +983,14 @@ void application_impl::unregister_availability_handler(service_t _service, } } -void application_impl::on_subscription(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, client_t _client, uid_t _uid, gid_t _gid, - bool _subscribed, std::function _accepted_cb) { +void application_impl::on_subscription( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + client_t _client, const vsomeip_sec_client_t *_sec_client, + const std::string &_env, bool _subscribed, + const std::function &_accepted_cb) { + bool handler_found = false; - std::pair its_handlers; + std::pair its_handlers; { std::lock_guard its_lock(subscription_mutex_); auto found_service = subscription_.find(_service); @@ -964,10 +1009,10 @@ void application_impl::on_subscription(service_t _service, instance_t _instance, if (handler_found) { if(auto its_handler = its_handlers.first) { // "normal" subscription handler exists - _accepted_cb(its_handler(_client, _uid, _gid, _subscribed)); + _accepted_cb(its_handler(_client, _sec_client, _env, _subscribed)); } else if(auto its_handler = its_handlers.second) { // async subscription handler exists - its_handler(_client, _uid, _gid, _subscribed, _accepted_cb); + its_handler(_client, _sec_client, _env, _subscribed, _accepted_cb); } } else { _accepted_cb(true); @@ -976,12 +1021,59 @@ void application_impl::on_subscription(service_t _service, instance_t _instance, void application_impl::register_subscription_handler(service_t _service, instance_t _instance, eventgroup_t _eventgroup, - subscription_handler_t _handler) { + const subscription_handler_t &_handler) { + + subscription_handler_ext_t its_handler_ext + = [_handler](client_t _client, uid_t _uid, gid_t _gid, + const std::string &_env, bool _is_subscribed) { + + (void)_env; // compatibility + return _handler(_client, _uid, _gid, _is_subscribed); + }; + + register_subscription_handler(_service, _instance, _eventgroup, + its_handler_ext); +} + +void application_impl::register_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + const subscription_handler_ext_t &_handler) { + + subscription_handler_sec_t its_handler_sec = [_handler]( + client_t _client, + const vsomeip_sec_client_t* _sec_client, + const std::string& _env, + bool _is_subscribed + ){ + uid_t its_uid{ANY_UID}; + gid_t its_gid{ANY_GID}; + + if (_sec_client && _sec_client->client_type == VSOMEIP_CLIENT_UDS) { + its_uid = _sec_client->client.uds_client.user; + its_gid = _sec_client->client.uds_client.group; + } + + return _handler( + _client, + its_uid, + its_gid, + _env, + _is_subscribed + ); + }; + + register_subscription_handler(_service, _instance, _eventgroup, its_handler_sec); +} + +void application_impl::register_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + const subscription_handler_sec_t &_handler) { std::lock_guard its_lock(subscription_mutex_); subscription_[_service][_instance][_eventgroup] = std::make_pair(_handler, nullptr); } + void application_impl::unregister_subscription_handler(service_t _service, instance_t _instance, eventgroup_t _eventgroup) { std::lock_guard its_lock(subscription_mutex_); @@ -997,40 +1089,49 @@ void application_impl::unregister_subscription_handler(service_t _service, } } -void application_impl::on_subscription_status(service_t _service, - instance_t _instance, eventgroup_t _eventgroup, event_t _event, - uint16_t _error) { +void application_impl::on_subscription_status( + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, event_t _event, uint16_t _error) { + bool entry_found(false); { - auto its_tuple = std::make_tuple(_service, _instance, _eventgroup, _event); std::lock_guard its_lock(subscriptions_state_mutex_); - auto its_subscription_state = subscription_state_.find(its_tuple); - if (its_subscription_state == subscription_state_.end()) { - its_tuple = std::make_tuple(_service, _instance, _eventgroup, ANY_EVENT); - auto its_any_subscription_state = subscription_state_.find(its_tuple); - if (its_any_subscription_state == subscription_state_.end()) { - VSOMEIP_TRACE << std::hex << get_client( ) - << " application_impl::on_subscription_status: " - << "Received a subscription status without subscribe for " - << std::hex << _service << "/" << _instance << "/" - << _eventgroup << "/" << _event << "/error=" << _error; - } else { - entry_found = true; - } - } else { - entry_found = true; - } - if (entry_found) { - if (_error) { - subscription_state_[its_tuple] = - subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED; - } else { - subscription_state_[its_tuple] = - subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED; + auto its_service = subscription_state_.find(_service); + if (its_service == subscription_state_.end()) + its_service = subscription_state_.find(ANY_SERVICE); + + if (its_service != subscription_state_.end()) { + auto its_instance = its_service->second.find(_instance); + if (its_instance == its_service->second.end()) + its_instance = its_service->second.find(ANY_INSTANCE); + + if (its_instance != its_service->second.end()) { + auto its_eventgroup = its_instance->second.find(_eventgroup); + if (its_eventgroup == its_instance->second.end()) + its_eventgroup = its_instance->second.find(ANY_EVENTGROUP); + + if (its_eventgroup != its_instance->second.end()) { + auto its_event = its_eventgroup->second.find(_event); + if (its_event == its_eventgroup->second.end()) + its_event = its_eventgroup->second.find(ANY_EVENT); + + if (its_event != its_eventgroup->second.end()) { + entry_found = true; + its_event->second = (_error ? + subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED : + subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED); + } + auto its_any_event = its_eventgroup->second.find(ANY_EVENT); + if (its_any_event != its_eventgroup->second.end()) { + entry_found = true; + its_any_event->second = (_error ? + subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED : + subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED); + } + } } } } - if (entry_found) { deliver_subscription_state(_service, _instance, _eventgroup, _event, _error); } @@ -1038,6 +1139,7 @@ void application_impl::on_subscription_status(service_t _service, void application_impl::deliver_subscription_state(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, uint16_t _error) { + std::vector handlers; { std::lock_guard its_lock(subscription_status_handlers_mutex_); @@ -1052,12 +1154,26 @@ void application_impl::deliver_subscription_state(service_t _service, instance_t if (!_error || (_error && found_event->second.second)) { handlers.push_back(found_event->second.first); } - } else { - auto its_any_event = found_eventgroup->second.find(ANY_EVENT); - if (its_any_event != found_eventgroup->second.end()) { - if (!_error || (_error && its_any_event->second.second)) { - handlers.push_back(its_any_event->second.first); - } + } + auto found_any_event = found_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); + } + } + } + auto found_any_eventgroup = found_instance->second.find(ANY_EVENTGROUP); + if (found_any_eventgroup != found_instance->second.end()) { + auto found_event = found_any_eventgroup->second.find(_event); + if (found_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_event->second.second)) { + handlers.push_back(found_event->second.first); + } + } + auto found_any_event = found_any_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); } } } @@ -1071,12 +1187,26 @@ void application_impl::deliver_subscription_state(service_t _service, instance_t if (!_error || (_error && found_event->second.second)) { handlers.push_back(found_event->second.first); } - } else { - auto its_any_event = found_eventgroup->second.find(ANY_EVENT); - if (its_any_event != found_eventgroup->second.end()) { - if (!_error || (_error && its_any_event->second.second)) { - handlers.push_back(its_any_event->second.first); - } + } + auto found_any_event = found_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); + } + } + } + auto found_any_eventgroup = found_instance->second.find(ANY_EVENTGROUP); + if (found_any_eventgroup != found_instance->second.end()) { + auto found_event = found_any_eventgroup->second.find(_event); + if (found_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_event->second.second)) { + handlers.push_back(found_event->second.first); + } + } + auto found_any_event = found_any_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); } } } @@ -1093,12 +1223,26 @@ void application_impl::deliver_subscription_state(service_t _service, instance_t if (!_error || (_error && found_event->second.second)) { handlers.push_back(found_event->second.first); } - } else { - auto its_any_event = found_eventgroup->second.find(ANY_EVENT); - if (its_any_event != found_eventgroup->second.end()) { - if (!_error || (_error && its_any_event->second.second)) { - handlers.push_back(its_any_event->second.first); - } + } + auto found_any_event = found_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); + } + } + } + auto found_any_eventgroup = found_instance->second.find(ANY_EVENTGROUP); + if (found_any_eventgroup != found_instance->second.end()) { + auto found_event = found_any_eventgroup->second.find(_event); + if (found_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_event->second.second)) { + handlers.push_back(found_event->second.first); + } + } + auto found_any_event = found_any_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); } } } @@ -1112,12 +1256,26 @@ void application_impl::deliver_subscription_state(service_t _service, instance_t if (!_error || (_error && found_event->second.second)) { handlers.push_back(found_event->second.first); } - } else { - auto its_any_event = found_eventgroup->second.find(ANY_EVENT); - if (its_any_event != found_eventgroup->second.end()) { - if (!_error || (_error && its_any_event->second.second)) { - handlers.push_back(its_any_event->second.first); - } + } + auto found_any_event = found_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); + } + } + } + auto found_any_eventgroup = found_instance->second.find(ANY_EVENTGROUP); + if (found_any_eventgroup != found_instance->second.end()) { + auto found_event = found_any_eventgroup->second.find(_event); + if (found_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_event->second.second)) { + handlers.push_back(found_event->second.first); + } + } + auto found_any_event = found_any_eventgroup->second.find(ANY_EVENT); + if (found_any_event != found_any_eventgroup->second.end()) { + if (!_error || (_error && found_any_event->second.second)) { + handlers.push_back(found_any_event->second.first); } } } @@ -1191,7 +1349,7 @@ void application_impl::unregister_subscription_status_handler(service_t _service } void application_impl::register_message_handler(service_t _service, - instance_t _instance, method_t _method, message_handler_t _handler) { + instance_t _instance, method_t _method, const message_handler_t &_handler) { std::lock_guard its_lock(members_mutex_); members_[_service][_instance][_method] = _handler; } @@ -1218,12 +1376,33 @@ void application_impl::offer_event(service_t _service, instance_t _instance, bool _update_on_change, const epsilon_change_func_t &_epsilon_change_func, reliability_type_e _reliability) { - if (routing_) + if (routing_) { + + if (_cycle == std::chrono::milliseconds::zero() + && _change_resets_cycle == false + && _update_on_change == true) { + + configuration_->get_event_update_properties( + _service, _instance, _notifier, + _cycle, _change_resets_cycle, _update_on_change); + + VSOMEIP_INFO << __func__ + << ": Event [" + << std::hex << std::setw(4) << std::setfill('0') + << _service << "." + << std::hex << std::setw(4) << std::setfill('0') + << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') + << _notifier << "] uses configured cycle time " + << std::dec << _cycle.count() << "ms"; + } + routing_->register_event(client_, _service, _instance, _notifier, _eventgroups, _type, _reliability, _cycle, _change_resets_cycle, _update_on_change, _epsilon_change_func, true); + } } void application_impl::stop_offer_event(service_t _service, instance_t _instance, @@ -1263,12 +1442,10 @@ void application_impl::set_client(const client_t &_client) { client_ = _client; } -session_t application_impl::get_session() { +session_t application_impl::get_session(bool _is_request) { -#ifdef VSOMEIP_HAS_SESSION_HANDLING_CONFIG - if (!has_session_handling_) + if (!has_session_handling_ && !_is_request) return (0); -#endif // VSOMEIP_HAS_SESSION_HANDLING_CONFIG std::lock_guard its_lock(session_mutex_); if (0 == ++session_) { @@ -1279,6 +1456,11 @@ session_t application_impl::get_session() { return session_; } +const vsomeip_sec_client_t *application_impl::get_sec_client() const { + + return &sec_client_; +} + std::shared_ptr application_impl::get_configuration() const { return configuration_; } @@ -1287,13 +1469,13 @@ diagnosis_t application_impl::get_diagnosis() const { return configuration_->get_diagnosis_address(); } -boost::asio::io_service & application_impl::get_io() { +boost::asio::io_context &application_impl::get_io() { return io_; } void application_impl::on_state(state_type_e _state) { { - std::lock_guard availability_lock(availability_mutex_); + std::lock_guard availability_lock(availability_mutex_); if (state_ != _state) { state_ = _state; if (state_ == state_type_e::ST_REGISTERED) { @@ -1302,7 +1484,7 @@ void application_impl::on_state(state_type_e _state) { for (const auto &its_major : its_instance.second) { for (const auto &its_minor : its_major.second) { if (!its_minor.second.second) { - do_register_availability_handler( + register_availability_handler_unlocked( its_service.first, its_instance.first, its_minor.second.first, @@ -1312,17 +1494,6 @@ void application_impl::on_state(state_type_e _state) { } } } - } else { - // Call on_availability callback on each service - for (const auto &its_service : availability_) { - for (const auto &its_instance : its_service.second) { - for (const auto &its_major : its_instance.second) { - for (const auto &its_minor : its_major.second) { - on_availability(its_service.first, its_instance.first, false, its_major.first, its_minor.first); - } - } - } - } } } } @@ -1348,16 +1519,17 @@ void application_impl::on_state(state_type_e _state) { } void application_impl::on_availability(service_t _service, instance_t _instance, - bool _is_available, major_version_t _major, minor_version_t _minor) { - std::vector its_handlers; + availability_state_e _state, major_version_t _major, minor_version_t _minor) { + + std::vector its_handlers; { - std::lock_guard availability_lock(availability_mutex_); - if (_is_available == is_available_unlocked(_service, _instance, _major, _minor)) { + std::lock_guard availability_lock(availability_mutex_); + if (_state == is_available_unlocked(_service, _instance, _major, _minor)) { return; } - if (_is_available) { - available_[_service][_instance][_major] = _minor; + if (_state != availability_state_e::AS_UNAVAILABLE) { + available_[_service][_instance][_major] = std::make_pair(_minor, _state); } else { auto found_available_service = available_.find(_service); if (found_available_service != available_.end()) { @@ -1365,7 +1537,7 @@ void application_impl::on_availability(service_t _service, instance_t _instance, if( found_instance != found_available_service->second.end()) { auto found_major = found_instance->second.find(_major); if( found_major != found_instance->second.end() ){ - if( _minor == found_major->second) + if(_minor == found_major->second.first) found_available_service->second.erase(_instance); } } @@ -1429,9 +1601,9 @@ void application_impl::on_availability(service_t _service, instance_t _instance, for (const auto &handler : its_handlers) { std::shared_ptr its_sync_handler = std::make_shared( - [handler, _service, _instance, _is_available]() + [handler, _service, _instance, _state]() { - handler(_service, _instance, _is_available); + handler(_service, _instance, _state); }); its_sync_handler->handler_type_ = handler_type_e::AVAILABILITY; its_sync_handler->service_id_ = _service; @@ -1440,7 +1612,7 @@ void application_impl::on_availability(service_t _service, instance_t _instance, } } } - if (!_is_available) { + if (_state == availability_state_e::AS_UNAVAILABLE) { { std::lock_guard its_lock(subscriptions_mutex_); auto found_service = subscriptions_.find(_service); @@ -1457,11 +1629,16 @@ void application_impl::on_availability(service_t _service, instance_t _instance, } { std::lock_guard its_lock(subscriptions_state_mutex_); - for (auto &its_subscription_state : subscription_state_) { - if (std::get<0>(its_subscription_state.first) == _service && - std::get<1>(its_subscription_state.first) == _instance) { - its_subscription_state.second = - subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED; + auto its_service = subscription_state_.find(_service); + if (its_service != subscription_state_.end()) { + auto its_instance = its_service->second.find(_instance); + if (its_instance != its_service->second.end()) { + for (auto &its_eventgroup : its_instance->second) { + for (auto &its_event : its_eventgroup.second) { + its_event.second + = subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED; + } + } } } } @@ -1481,10 +1658,11 @@ void application_impl::on_message(std::shared_ptr &&_message) { if (_message->get_message_type() == message_type_e::MT_NOTIFICATION) { if (!check_for_active_subscription(its_service, its_instance, static_cast(its_method))) { - VSOMEIP_ERROR << "application_impl::on_message [" + VSOMEIP_INFO << "application_impl::on_message [" << std::hex << std::setw(4) << std::setfill('0') << its_service << "." << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." - << std::hex << std::setw(4) << std::setfill('0') << its_method << "]"; + << std::hex << std::setw(4) << std::setfill('0') << its_method << "]" + << ": blocked as the subscription is already inactive."; return; } } @@ -1569,7 +1747,7 @@ routing_manager * application_impl::get_routing_manager() const { } void application_impl::main_dispatch() { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) { std::stringstream s; s << std::hex << std::setw(4) << std::setfill('0') @@ -1581,7 +1759,7 @@ void application_impl::main_dispatch() { VSOMEIP_INFO << "main dispatch thread id from application: " << std::hex << std::setw(4) << std::setfill('0') << client_ << " (" << name_ << ") is: " << std::hex << its_id -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) << " TID: " << std::dec << static_cast(syscall(SYS_gettid)) #endif ; @@ -1591,9 +1769,10 @@ void application_impl::main_dispatch() { // Cancel other waiting dispatcher dispatcher_condition_.notify_all(); // Wait for new handlers to execute - while (is_dispatching_ && (handlers_.empty() || !is_active_dispatcher(its_id))) { - dispatcher_condition_.wait(its_lock); - } + dispatcher_condition_.wait(its_lock, [this, &its_id] { + return !(is_dispatching_ + && (handlers_.empty() || !is_active_dispatcher(its_id))); + }); } else { std::shared_ptr its_handler; while (is_dispatching_ && is_active_dispatcher(its_id) @@ -1622,7 +1801,7 @@ void application_impl::main_dispatch() { } void application_impl::dispatch() { -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) { std::stringstream s; s << std::hex << std::setw(4) << std::setfill('0') @@ -1634,14 +1813,15 @@ void application_impl::dispatch() { VSOMEIP_INFO << "dispatch thread id from application: " << std::hex << std::setw(4) << std::setfill('0') << client_ << " (" << name_ << ") is: " << std::hex << its_id -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) << " TID: " << std::dec << static_cast(syscall(SYS_gettid)) #endif ; std::unique_lock its_lock(handlers_mutex_); while (is_active_dispatcher(its_id)) { if (is_dispatching_ && handlers_.empty()) { - dispatcher_condition_.wait(its_lock); + dispatcher_condition_.wait(its_lock, + [this, &its_id] { return !is_active_dispatcher(its_id); }); // Maybe woken up from main dispatcher if (handlers_.empty() && !is_active_dispatcher(its_id)) { if (!is_dispatching_) { @@ -1775,7 +1955,9 @@ void application_impl::invoke_handler(std::shared_ptr &_handler) { << get_client() << " is shutting down"; } } else { - VSOMEIP_ERROR << "Maximum number of dispatchers exceeded."; + VSOMEIP_ERROR << "Maximum number of dispatchers exceeded. Configuration: " + << " Max dispatchers: " << std::dec << max_dispatchers_ + << " Max dispatch time: " << std::dec << max_dispatch_time_; } dispatcher_mutex_.unlock(); break; @@ -1889,7 +2071,7 @@ void application_impl::clear_all_handler() { } { - std::lock_guard availability_lock(availability_mutex_); + std::lock_guard availability_lock(availability_mutex_); availability_.clear(); } @@ -1917,11 +2099,11 @@ void application_impl::shutdown() { VSOMEIP_INFO << "shutdown thread id from application: " << std::hex << std::setw(4) << std::setfill('0') << client_ << " (" << name_ << ") is: " << std::hex << std::this_thread::get_id() -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) << " TID: " << std::dec << static_cast(syscall(SYS_gettid)) #endif ; -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) boost::asio::detail::posix_signal_blocker blocker; { std::stringstream s; @@ -1933,9 +2115,7 @@ void application_impl::shutdown() { { std::unique_lock its_lock(start_stop_mutex_); - while(!stopped_) { - stop_cv_.wait(its_lock); - } + stop_cv_.wait(its_lock, [this] {return stopped_; }); } { std::lock_guard its_handler_lock(handlers_mutex_); @@ -2102,9 +2282,28 @@ void application_impl::remove_subscription(service_t _service, event_t _event) { { - auto its_tuple = std::make_tuple(_service, _instance, _eventgroup, _event); std::lock_guard its_lock(subscriptions_state_mutex_); - subscription_state_.erase(its_tuple); + auto its_service = subscription_state_.find(_service); + if (its_service != subscription_state_.end()) { + auto its_instance = its_service->second.find(_instance); + if (its_instance != its_service->second.end()) { + if (_event == ANY_EVENT) { + its_instance->second.erase(_eventgroup); + } else { + auto its_eventgroup = its_instance->second.find(_eventgroup); + if (its_eventgroup != its_instance->second.end()) { + its_eventgroup->second.erase(_event); + if (its_eventgroup->second.empty()) { + its_instance->second.erase(_eventgroup); + } + } + } + if (its_instance->second.empty()) + its_service->second.erase(its_instance); + } + if (its_service->second.empty()) + subscription_state_.erase(its_service); + } } std::lock_guard its_lock(subscriptions_mutex_); @@ -2157,7 +2356,7 @@ bool application_impl::check_for_active_subscription(service_t _service, std::shared_ptr its_event = routing_->find_event( _service, _instance, _event); if (its_event) { - for (const auto& eg : its_event->get_eventgroups()) { + for (const auto eg : its_event->get_eventgroups()) { auto found_eventgroup = found_any_event->second.find(eg); if (found_eventgroup != found_any_event->second.end()) { // set the flag for initial event received to true @@ -2183,25 +2382,39 @@ bool application_impl::check_for_active_subscription(service_t _service, bool application_impl::check_subscription_state(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event) { + bool is_acknowledged(false); bool should_subscribe(true); { - auto its_tuple = std::make_tuple(_service, _instance, _eventgroup, _event); + bool has_found(false); + std::lock_guard its_lock(subscriptions_state_mutex_); - auto its_subscription_state = subscription_state_.find(its_tuple); - if (its_subscription_state != subscription_state_.end()) { - if (its_subscription_state->second != - subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED) { - // only return true if subscription is NACK - // as only then we need to subscribe! - should_subscribe = false; - if (its_subscription_state->second == - subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED) { - is_acknowledged = true; + auto its_service = subscription_state_.find(_service); + if (its_service != subscription_state_.end()) { + auto its_instance = its_service->second.find(_instance); + if (its_instance != its_service->second.end()) { + auto its_eventgroup = its_instance->second.find(_eventgroup); + if (its_eventgroup != its_instance->second.end()) { + auto its_event = its_eventgroup->second.find(_event); + if (its_event != its_eventgroup->second.end()) { + if (its_event->second != subscription_state_e::SUBSCRIPTION_NOT_ACKNOWLEDGED) { + has_found = true; + + // only return true if subscription is NACK + // as only then we need to subscribe! + should_subscribe = false; + if (its_event->second == subscription_state_e::SUBSCRIPTION_ACKNOWLEDGED) { + is_acknowledged = true; + } + } + } } } - } else { - subscription_state_[its_tuple] = subscription_state_e::IS_SUBSCRIBING; + } + + if (!has_found) { + subscription_state_[_service][_instance][_eventgroup][_event] + = subscription_state_e::IS_SUBSCRIBING; } } @@ -2257,7 +2470,8 @@ void application_impl::print_blocking_call(const std::shared_ptr& } -void application_impl::get_offered_services_async(offer_type_e _offer_type, offered_services_handler_t _handler) { +void application_impl::get_offered_services_async(offer_type_e _offer_type, + const offered_services_handler_t &_handler) { { std::lock_guard its_lock(offered_services_handler_mutex_); offered_services_handler_ = _handler; @@ -2343,7 +2557,7 @@ void application_impl::watchdog_cbk(boost::system::error_code const &_error) { } } -void application_impl::set_watchdog_handler(watchdog_handler_t _handler, +void application_impl::set_watchdog_handler(const watchdog_handler_t &_handler, std::chrono::seconds _interval) { if (_handler && std::chrono::seconds::zero() != _interval) { std::lock_guard its_lock(watchdog_timer_mutex_); @@ -2362,14 +2576,63 @@ void application_impl::set_watchdog_handler(watchdog_handler_t _handler, void application_impl::register_async_subscription_handler(service_t _service, instance_t _instance, eventgroup_t _eventgroup, - async_subscription_handler_t _handler) { + const async_subscription_handler_t &_handler) { + + async_subscription_handler_ext_t its_handler_ext + = [_handler](client_t _client, uid_t _uid, gid_t _gid, + const std::string &_env, bool _is_subscribed, + const std::function< void (const bool) > &_cb) { + + (void)_env; // compatibility + _handler(_client, _uid, _gid, _is_subscribed, _cb); + }; + + register_async_subscription_handler(_service, _instance, _eventgroup, + its_handler_ext); +} + +void application_impl::register_async_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + const async_subscription_handler_ext_t &_handler) { + + async_subscription_handler_sec_t its_handler_sec = [_handler]( + client_t _client, + const vsomeip_sec_client_t* _sec_client, + const std::string& _env, + bool _is_subscribed, + const std::function &_cb + ){ + uid_t its_uid{ANY_UID}; + gid_t its_gid{ANY_GID}; + + if (_sec_client && _sec_client->client_type == VSOMEIP_CLIENT_UDS) { + its_uid = _sec_client->client.uds_client.user; + its_gid = _sec_client->client.uds_client.group; + } + + _handler( + _client, + its_uid, + its_gid, + _env, + _is_subscribed, + _cb + ); + }; + + register_async_subscription_handler(_service, _instance, _eventgroup, its_handler_sec); +} + +void application_impl::register_async_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + async_subscription_handler_sec_t _handler) { std::lock_guard its_lock(subscription_mutex_); - subscription_[_service][_instance][_eventgroup] = std::make_pair(nullptr, _handler);; + subscription_[_service][_instance][_eventgroup] = std::make_pair(nullptr, _handler); } void application_impl::register_sd_acceptance_handler( - sd_acceptance_handler_t _handler) { + const sd_acceptance_handler_t &_handler) { if (is_routing() && routing_) { const auto rm_impl = std::dynamic_pointer_cast(routing_); rm_impl->register_sd_acceptance_handler(_handler); @@ -2377,7 +2640,7 @@ void application_impl::register_sd_acceptance_handler( } void application_impl::register_reboot_notification_handler( - reboot_notification_handler_t _handler) { + const reboot_notification_handler_t &_handler) { if (is_routing() && routing_) { const auto rm_impl = std::dynamic_pointer_cast(routing_); rm_impl->register_reboot_notification_handler(_handler); @@ -2519,7 +2782,7 @@ application_impl::get_sd_acceptance_required() { } void application_impl::register_routing_ready_handler( - routing_ready_handler_t _handler) { + const routing_ready_handler_t &_handler) { if (is_routing() && routing_) { const auto rm_impl = std::dynamic_pointer_cast(routing_); rm_impl->register_routing_ready_handler(_handler); @@ -2527,7 +2790,7 @@ void application_impl::register_routing_ready_handler( } void application_impl::register_routing_state_handler( - routing_state_handler_t _handler) { + const routing_state_handler_t &_handler) { if (is_routing() && routing_) { const auto rm_impl = std::dynamic_pointer_cast(routing_); rm_impl->register_routing_state_handler(_handler); @@ -2565,7 +2828,14 @@ void application_impl::update_security_policy_configuration(uint32_t _uid, uint32_t _gid, ::std::shared_ptr _policy, std::shared_ptr _payload, - security_update_handler_t _handler) { + const security_update_handler_t &_handler) { +#ifdef VSOMEIP_DISABLE_SECURITY + (void)_uid; + (void)_gid; + (void)_policy; + (void)_payload; + (void)_handler; +#else if (!is_routing()) { VSOMEIP_ERROR << __func__ << " is only intended to be called by " "application acting as routing manager host"; @@ -2577,11 +2847,17 @@ void application_impl::update_security_policy_configuration(uint32_t _uid, rm_impl->update_security_policy_configuration(_uid, _gid, _policy, _payload, _handler); } } +#endif // VSOMEIP_DISABLE_SECURITY } void application_impl::remove_security_policy_configuration(uint32_t _uid, uint32_t _gid, - security_update_handler_t _handler) { + const security_update_handler_t &_handler) { +#ifdef VSOMEIP_DISABLE_SECURITY + (void)_uid; + (void)_gid; + (void)_handler; +#else if (!is_routing()) { VSOMEIP_ERROR << __func__ << " is only intended to be called by " "application acting as routing manager host"; @@ -2593,6 +2869,65 @@ void application_impl::remove_security_policy_configuration(uint32_t _uid, rm_impl->remove_security_policy_configuration(_uid, _gid, _handler); } } +#endif // !VSOMEIP_DISABLE_SECURITY +} + +void application_impl::subscribe_with_debounce(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const debounce_filter_t &_filter) { + + if (routing_) { + bool send_back_cached(false); + bool send_back_cached_group(false); + check_send_back_cached_event(_service, _instance, _event, _eventgroup, + &send_back_cached, &send_back_cached_group); + + if (send_back_cached) { + send_back_cached_event(_service, _instance, _event); + } else if(send_back_cached_group) { + send_back_cached_eventgroup(_service, _instance, _eventgroup); + } + + if (check_subscription_state(_service, _instance, _eventgroup, _event)) { + + auto its_filter = std::make_shared(_filter); + routing_->subscribe(client_, get_sec_client(), + _service, _instance, _eventgroup, _major, + _event, its_filter); + } + } +} + +bool +application_impl::is_local_endpoint(const boost::asio::ip::address &_unicast, + port_t _port) { + + try { + boost::asio::ip::tcp::endpoint its_endpoint(_unicast, _port); + boost::asio::ip::tcp::socket its_socket(io_, its_endpoint); + its_socket.close(); + + return (true); + } catch (...) { + } + + return (false); +} + +void application_impl::register_message_acceptance_handler( + const message_acceptance_handler_t &_handler) { + if (is_routing() && routing_) { + const auto rm_impl = std::dynamic_pointer_cast(routing_); + rm_impl->register_message_acceptance_handler(_handler); + } +} + +std::map +application_impl::get_additional_data(const std::string &_plugin_name) { + if (configuration_) { + return configuration_->get_additional_data(name_, _plugin_name); + } + return std::map(); } } // namespace vsomeip_v3 diff --git a/implementation/runtime/src/runtime.cpp b/implementation/runtime/src/runtime.cpp index 40bb455..b2fab88 100644 --- a/implementation/runtime/src/runtime.cpp +++ b/implementation/runtime/src/runtime.cpp @@ -1,15 +1,11 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include -#include #include "../include/runtime_impl.hpp" -#include "../../endpoints/include/endpoint.hpp" -#include "../../endpoints/include/client_endpoint.hpp" -#include "../../configuration/include/configuration_plugin.hpp" namespace vsomeip_v3 { @@ -25,19 +21,4 @@ std::shared_ptr runtime::get() { return runtime_impl::get(); } -// non-inline destructors to make typeinfo of the type visible outside the shared library boundary -#ifdef ANDROID -plugin::~plugin() { -} - -endpoint::~endpoint() { -} - -client_endpoint::~client_endpoint() { -} - -configuration_plugin::~configuration_plugin() { -} -#endif - } // namespace vsomeip_v3 diff --git a/implementation/runtime/src/runtime_impl.cpp b/implementation/runtime/src/runtime_impl.cpp index fc23ced..cf74b2f 100644 --- a/implementation/runtime/src/runtime_impl.cpp +++ b/implementation/runtime/src/runtime_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -35,15 +35,22 @@ runtime_impl::~runtime_impl() { std::shared_ptr runtime_impl::create_application( const std::string &_name) { + + return (create_application(_name, "")); +} + +std::shared_ptr runtime_impl::create_application( + const std::string &_name, const std::string &_path) { static std::uint32_t postfix_id = 0; std::lock_guard its_lock(applications_mutex_); - std::string its_name_ = _name; + std::string its_name = _name; auto found_application = applications_.find(_name); if( found_application != applications_.end()) { - its_name_ += "_" + std::to_string(postfix_id++); + its_name += "_" + std::to_string(postfix_id++); } - std::shared_ptr application = std::make_shared(its_name_); - applications_[its_name_] = application; + std::shared_ptr application + = std::make_shared(its_name, _path); + applications_[its_name] = application; return application; } diff --git a/implementation/security/include/policy.hpp b/implementation/security/include/policy.hpp index 82f3eb9..3c9760c 100644 --- a/implementation/security/include/policy.hpp +++ b/implementation/security/include/policy.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/security/include/policy_manager_impl.hpp b/implementation/security/include/policy_manager_impl.hpp index a5a30ea..4dd3a86 100644 --- a/implementation/security/include/policy_manager_impl.hpp +++ b/implementation/security/include/policy_manager_impl.hpp @@ -1,29 +1,48 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef VSOMEIP_V3_POLICY_MANAGER_IMPL_HPP_ -#define VSOMEIP_V3_POLICY_MANAGER_IMPL_HPP_ +#ifndef VSOMEIP_V3_SECURITY_POLICY_MANAGER_IMPL_HPP_ +#define VSOMEIP_V3_SECURITY_POLICY_MANAGER_IMPL_HPP_ -#include +#include #include +#include +#include -#include +#include +#include +#include + +#include #include +#include #include "../include/policy.hpp" -#include "../../configuration/include/configuration_element.hpp" namespace vsomeip_v3 { -class policy_manager_impl - : public policy_manager { +struct configuration_element; + +class VSOMEIP_IMPORT_EXPORT policy_manager_impl +#ifndef VSOMEIP_DISABLE_SECURITY + : public policy_manager +#endif // !VSOMEIP_DISABLE_SECURITY +{ public: - static std::shared_ptr get(); + enum class policy_loaded_e : std::uint8_t { + POLICY_PATH_FOUND_AND_LOADED = 0x0, + POLICY_PATH_FOUND_AND_NOT_LOADED = 0x1, + POLICY_PATH_INEXISTENT = 0x2 + }; - virtual ~policy_manager_impl(); + static std::shared_ptr get(); + policy_manager_impl(); + +#ifndef VSOMEIP_DISABLE_SECURITY + // policy_manager interface std::shared_ptr create_policy() const; void print_policy(const std::shared_ptr &_policy) const; @@ -36,8 +55,144 @@ public: bool is_policy_update_allowed(uint32_t _uid, std::shared_ptr &_policy) const; bool is_policy_removal_allowed(uint32_t _uid) const; + + // extension + void load(const configuration_element &_element, + const bool _lazy_load = false); + + void update_security_policy(uint32_t _uid, uint32_t _gid, const std::shared_ptr& _policy); + bool remove_security_policy(uint32_t _uid, uint32_t _gid); + + void add_security_credentials(uint32_t _uid, uint32_t _gid, + const std::shared_ptr& _credentials_policy, client_t _client); + + void get_requester_policies(const std::shared_ptr _policy, + std::set > &_requesters) const; + void get_clients(uid_t _uid, gid_t _gid, std::unordered_set &_clients) const; + + bool is_policy_extension(const std::string &_path) const; + std::string get_policy_extension_path(const std::string &_client_host) const; + + void set_policy_extension_base_path(const std::string &_path); + std::string get_security_config_folder(const std::string &its_folder) const; + std::string get_policy_extension_path_unlocked(const std::string &_client_host) const; + + policy_loaded_e is_policy_extension_loaded(const std::string &_client_host) const; + void set_is_policy_extension_loaded(const std::string &_client_host, const bool _loaded); + +private: + + // Configuration + void load_policies(const configuration_element &_element); + void load_policy(const boost::property_tree::ptree &_tree); + void load_policy_body(std::shared_ptr &_policy, + const boost::property_tree::ptree::const_iterator &_tree); + void load_credential(const boost::property_tree::ptree &_tree, + boost::icl::interval_map > &_ids); + bool load_routing_credentials(const configuration_element &_element); + template + void load_interval_set(const boost::property_tree::ptree &_tree, + boost::icl::interval_set &_range, bool _exclude_margins = false); + void load_security_update_whitelist(const configuration_element &_element); + void load_security_policy_extensions(const configuration_element &_element); +#endif // !VSOMEIP_DISABLE_SECURITY + +public: + bool is_enabled() const; + bool is_audit() const; + + bool check_credentials(client_t _client, + const vsomeip_sec_client_t *_sec_client); + bool check_routing_credentials( + const vsomeip_sec_client_t *_sec_client) const; + void set_routing_credentials(uint32_t _uid, uint32_t _gid, + const std::string &_name); + + bool is_client_allowed(const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, method_t _method, + bool _is_request_service = false) const; + bool is_offer_allowed(const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance) const; + + bool get_sec_client_to_clients_mapping(const vsomeip_sec_client_t *_sec_client, + std::set &_clients); + bool remove_client_to_sec_client_mapping(client_t _client); + + bool get_client_to_sec_client_mapping(client_t _client, vsomeip_sec_client_t &_sec_client); + bool store_client_to_sec_client_mapping(client_t _client, const vsomeip_sec_client_t *_sec_client); + void store_sec_client_to_client_mapping(const vsomeip_sec_client_t *_sec_client, client_t _client); + +private: +#ifdef _WIN32 +#pragma warning(push) +#pragma warning(disable : 4251) +#endif +#ifndef VSOMEIP_DISABLE_SECURITY + mutable boost::shared_mutex any_client_policies_mutex_; + std::vector > any_client_policies_; + + mutable boost::shared_mutex is_client_allowed_cache_mutex_; + mutable std::map, + std::set > + > is_client_allowed_cache_; + + bool policy_enabled_; + bool check_credentials_; + bool allow_remote_clients_; + bool check_whitelist_; + + mutable std::mutex service_interface_whitelist_mutex_; + boost::icl::interval_set service_interface_whitelist_; + + mutable std::mutex uid_whitelist_mutex_; + boost::icl::interval_set uid_whitelist_; + + mutable std::mutex policy_base_path_mutex_; + std::string policy_base_path_; + + mutable boost::shared_mutex policy_extension_paths_mutex_; + //map[hostname, pair[path, map[complete path with UID/GID, control loading]] + std::map>> policy_extension_paths_; +#endif // !VSOMEIP_DISABLE_SECURITY + + bool is_configured_; + bool check_routing_credentials_; + + mutable std::mutex routing_credentials_mutex_; + std::pair routing_credentials_; + + mutable std::mutex ids_mutex_; + std::map ids_; + + struct vsomeip_sec_client_comparator_t { + bool operator()(const vsomeip_sec_client_t &_lhs, const vsomeip_sec_client_t &_rhs) const { + if (_lhs.client_type < _rhs.client_type) { + return true; + } else if (_lhs.client_type == _rhs.client_type) { + switch (_lhs.client_type) { + case VSOMEIP_CLIENT_UDS: + return ((_lhs.client.uds_client.user < _rhs.client.uds_client.user) + || ((_lhs.client.uds_client.user == _rhs.client.uds_client.user) + && (_lhs.client.uds_client.group < _rhs.client.uds_client.group))); + case VSOMEIP_CLIENT_TCP: + return ((_lhs.client.ip_client.ip < _rhs.client.ip_client.ip) + || ((_lhs.client.ip_client.ip == _rhs.client.ip_client.ip) + && (_lhs.client.ip_client.port < _rhs.client.ip_client.port))); + default: + ; + } + } + return false; + } + }; + + mutable std::mutex sec_client_to_clients_mutex_; + std::map, vsomeip_sec_client_comparator_t> sec_client_to_clients_; +#ifdef _WIN32 +#pragma warning(pop) +#endif }; } // namespace vsomeip_v3 -#endif // VSOMEIP_V3_POLICY_MANAGER_IMPL_HPP_ +#endif // VSOMEIP_V3_SECURITY_POLICY_MANAGER_IMPL_HPP_ diff --git a/implementation/security/include/security.hpp b/implementation/security/include/security.hpp index 03406c6..1affb0c 100644 --- a/implementation/security/include/security.hpp +++ b/implementation/security/include/security.hpp @@ -1,65 +1,34 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef VSOMEIP_V3_SECURITY_SECURITY_HPP_ -#define VSOMEIP_V3_SECURITY_SECURITY_HPP_ +#ifndef VSOMEIP_V3_SECURITY_HPP_ +#define VSOMEIP_V3_SECURITY_HPP_ -#include -#include - -#include -#include +#include +#include namespace vsomeip_v3 { -struct configuration_element; - -class security { +class VSOMEIP_IMPORT_EXPORT security { public: - VSOMEIP_EXPORT static std::shared_ptr get(); - - virtual ~security() {}; - - virtual void load(const configuration_element &_element) = 0; - - virtual bool is_enabled() const = 0; - virtual bool is_audit() const = 0; - - virtual bool check_credentials(client_t _client, uid_t _uid, gid_t _gid) = 0; - virtual bool check_routing_credentials(client_t _client, - uint32_t _uid, uint32_t _gid) const = 0; - - virtual bool is_client_allowed(uint32_t _uid, uint32_t _gid, client_t _client, - service_t _service, instance_t _instance, method_t _method, - bool _is_request_service = false) const = 0; - virtual bool is_remote_client_allowed() const = 0; - virtual bool is_offer_allowed(uint32_t _uid, uint32_t _gid, client_t _client, - service_t _service, instance_t _instance) const = 0; - - virtual void update_security_policy(uint32_t _uid, uint32_t _gid, - const std::shared_ptr& _policy) = 0; - virtual bool remove_security_policy(uint32_t _uid, uint32_t _gid) = 0; - - virtual bool get_uid_gid_to_client_mapping(std::pair _uid_gid, - std::set &_clients) = 0; - virtual bool remove_client_to_uid_gid_mapping(client_t _client) = 0; - - virtual bool get_client_to_uid_gid_mapping(client_t _client, - std::pair &_uid_gid) = 0; - - virtual bool store_client_to_uid_gid_mapping(client_t _client, - uint32_t _uid, uint32_t _gid) = 0; - virtual void store_uid_gid_to_client_mapping(uint32_t _uid, uint32_t _gid, - client_t _client) = 0; - - virtual void get_requester_policies(const std::shared_ptr _policy, - std::set > &_requesters) const = 0; - virtual void get_clients(uid_t _uid, gid_t _gid, - std::unordered_set &_clients) const = 0; + static bool load(); + + static decltype(&vsomeip_sec_policy_initialize) initialize; + static decltype(&vsomeip_sec_policy_authenticate_router) authenticate_router; + static decltype(&vsomeip_sec_policy_is_client_allowed_to_offer) is_client_allowed_to_offer; + static decltype(&vsomeip_sec_policy_is_client_allowed_to_request) is_client_allowed_to_request; + static decltype(&vsomeip_sec_policy_is_client_allowed_to_access_member) is_client_allowed_to_access_member; + +private: + static decltype(vsomeip_sec_policy_initialize) default_initialize; + static decltype(vsomeip_sec_policy_authenticate_router) default_authenticate_router; + static decltype(vsomeip_sec_policy_is_client_allowed_to_offer) default_is_client_allowed_to_offer; + static decltype(vsomeip_sec_policy_is_client_allowed_to_request) default_is_client_allowed_to_request; + static decltype(vsomeip_sec_policy_is_client_allowed_to_access_member) default_is_client_allowed_to_access_member; }; } // namespace vsomeip_v3 -#endif // VSOMEIP_V3_SECURITY_SECURITY_HPP_ +#endif // VSOMEIP_V3_SECURITY_HPP_ diff --git a/implementation/security/include/security_impl.hpp b/implementation/security/include/security_impl.hpp deleted file mode 100644 index dfeea6b..0000000 --- a/implementation/security/include/security_impl.hpp +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef VSOMEIP_V3_SECURITY_IMPL_HPP_ -#define VSOMEIP_V3_SECURITY_IMPL_HPP_ - -#include -#include -#include - -#include - -#include "../include/policy.hpp" -#include "../include/security.hpp" - -namespace vsomeip_v3 { - -class security_impl : - public security { -public: - static std::shared_ptr get(); - - security_impl(); - - void load(const configuration_element &_element); - - bool is_enabled() const; - bool is_audit() const; - - bool check_credentials(client_t _client, uid_t _uid, gid_t _gid); - bool check_routing_credentials(client_t _client, uint32_t _uid, uint32_t _gid) const; - - bool is_client_allowed(uint32_t _uid, uint32_t _gid, client_t _client, - service_t _service, instance_t _instance, method_t _method, - bool _is_request_service = false) const; - bool is_offer_allowed(uint32_t _uid, uint32_t _gid, client_t _client, - service_t _service, instance_t _instance) const; - - void update_security_policy(uint32_t _uid, uint32_t _gid, const std::shared_ptr& _policy); - bool remove_security_policy(uint32_t _uid, uint32_t _gid); - - void add_security_credentials(uint32_t _uid, uint32_t _gid, - const std::shared_ptr& _credentials_policy, client_t _client); - - bool is_remote_client_allowed() const; - - bool is_policy_update_allowed(uint32_t _uid, std::shared_ptr &_policy) const; - - bool is_policy_removal_allowed(uint32_t _uid) const; - - bool parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, - uint32_t &_uid, uint32_t &_gid, const std::shared_ptr &_policy) const; - - bool get_uid_gid_to_client_mapping(std::pair _uid_gid, std::set &_clients); - bool remove_client_to_uid_gid_mapping(client_t _client); - - bool get_client_to_uid_gid_mapping(client_t _client, std::pair &_uid_gid); - bool store_client_to_uid_gid_mapping(client_t _client, uint32_t _uid, uint32_t _gid); - void store_uid_gid_to_client_mapping(uint32_t _uid, uint32_t _gid, client_t _client); - - void get_requester_policies(const std::shared_ptr _policy, - std::set > &_requesters) const; - void get_clients(uid_t _uid, gid_t _gid, std::unordered_set &_clients) const; - -private: - - // Configuration - void load_policies(const configuration_element &_element); - void load_policy(const boost::property_tree::ptree &_tree); - void load_policy_body(std::shared_ptr &_policy, - const boost::property_tree::ptree::const_iterator &_tree); - void load_credential(const boost::property_tree::ptree &_tree, - boost::icl::interval_map > &_ids); - bool load_routing_credentials(const configuration_element &_element); - template - void load_interval_set(const boost::property_tree::ptree &_tree, - boost::icl::interval_set &_range, bool _exclude_margins = false); - void load_security_update_whitelist(const configuration_element &_element); - -private: - client_t routing_client_; - - mutable std::mutex ids_mutex_; - mutable std::mutex uid_to_clients_mutex_; - - std::vector > any_client_policies_; - - mutable std::mutex any_client_policies_mutex_; - std::map > ids_; - std::map, std::set > uid_to_clients_; - - bool policy_enabled_; - bool check_credentials_; - bool check_routing_credentials_; - bool allow_remote_clients_; - bool check_whitelist_; - - mutable std::mutex service_interface_whitelist_mutex_; - boost::icl::interval_set service_interface_whitelist_; - - mutable std::mutex uid_whitelist_mutex_; - boost::icl::interval_set uid_whitelist_; - - mutable std::mutex routing_credentials_mutex_; - std::pair routing_credentials_; - - bool is_configured_; -}; - -} // namespace vsomeip_v3 - -#endif // VSOMEIP_V3_SECURITY_IMPL_HPP_ diff --git a/implementation/security/src/policy.cpp b/implementation/security/src/policy.cpp index 260198a..b582712 100644 --- a/implementation/security/src/policy.cpp +++ b/implementation/security/src/policy.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -175,7 +175,7 @@ policy::deserialize_ids(const byte_t * &_data, uint32_t &_size, if (its_result == false) return (false); - for (const auto& i : its_instances) + for (const auto i : its_instances) its_ids += std::make_pair(i, its_methods); its_array_length -= (its_current_size - _size); @@ -202,7 +202,8 @@ policy::deserialize_id_item_list(const byte_t * &_data, uint32_t &_size, uint32_t its_current_size(_size); - uint16_t its_low, its_high; + uint16_t its_low = 0; + uint16_t its_high = 0; its_result = deserialize_id_item(_data, _size, its_low, its_high); if (its_result == false) return (false); @@ -378,7 +379,7 @@ policy::serialize_interval_set( uint32_t its_interval_set_size(0); serialize_u32(its_interval_set_size, _data); - for (const auto& i : _intervals) + for (const auto i : _intervals) serialize_interval(i, _data); its_interval_set_size = static_cast(_data.size() diff --git a/implementation/security/src/policy_manager.cpp b/implementation/security/src/policy_manager.cpp index beae85c..ad1b52e 100644 --- a/implementation/security/src/policy_manager.cpp +++ b/implementation/security/src/policy_manager.cpp @@ -5,13 +5,13 @@ #include "../include/policy_manager_impl.hpp" +#ifndef VSOMEIP_DISABLE_SECURITY namespace vsomeip_v3 { std::shared_ptr policy_manager::get() { - static std::shared_ptr the_policy_manager - = std::make_shared(); - return the_policy_manager; + return policy_manager_impl::get(); } } // namespace vsomeip_v3 +#endif diff --git a/implementation/security/src/policy_manager_impl.cpp b/implementation/security/src/policy_manager_impl.cpp index a816714..849a36b 100644 --- a/implementation/security/src/policy_manager_impl.cpp +++ b/implementation/security/src/policy_manager_impl.cpp @@ -1,15 +1,1281 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../include/policy.hpp" +#ifdef _WIN32 + #define WIN32_LEAN_AND_MEAN + #define NOMINMAX + #include + #include +#endif + +#include +#include + #include "../include/policy_manager_impl.hpp" -#include "../include/security_impl.hpp" +#include "../../configuration/include/configuration_element.hpp" +#ifdef ANDROID +#include "../../configuration/include/internal_android.hpp" +#else +#include "../../configuration/include/internal.hpp" +#endif // ANDROID +#include "../../utility/include/utility.hpp" namespace vsomeip_v3 { -policy_manager_impl::~policy_manager_impl() { +template +void read_data(const std::string &_in, T_ &_out) { + std::stringstream its_converter; + + if (_in.size() > 2 + && _in[0] == '0' + && (_in[1] == 'x' || _in[1] == 'X')) + its_converter << std::hex << _in; + else + its_converter << std::dec << _in; + + its_converter >> _out; +} + +policy_manager_impl::policy_manager_impl() + : +#ifndef VSOMEIP_DISABLE_SECURITY + policy_enabled_(false), + check_credentials_(false), + allow_remote_clients_(true), + check_whitelist_(false), + policy_base_path_(""), +#endif // !VSOMEIP_DISABLE_SECURITY + is_configured_(false), + check_routing_credentials_(false) +{ +} + +bool +policy_manager_impl::is_enabled() const { +#ifdef VSOMEIP_DISABLE_SECURITY + return (false); +#else + return (policy_enabled_); +#endif +} + +bool +policy_manager_impl::is_audit() const { +#ifdef VSOMEIP_DISABLE_SECURITY + return (false); +#else + return (!check_credentials_); +#endif +} + +bool +policy_manager_impl::check_credentials(client_t _client, + const vsomeip_sec_client_t *_sec_client) { + +#ifdef VSOMEIP_DISABLE_SECURITY + (void)_client; + (void)_sec_client; + + return (true); +#else + if (!policy_enabled_) + return (true); + + if (!_sec_client) + return (true); + + if (_sec_client->client_type != VSOMEIP_CLIENT_UDS) + return (true); + + uid_t its_uid(_sec_client->client.uds_client.user); + gid_t its_gid(_sec_client->client.uds_client.group); + + bool has_id(false); + + boost::shared_lock its_lock(any_client_policies_mutex_); + for (const auto &p : any_client_policies_) { + + std::lock_guard its_policy_lock(p->mutex_); + + bool has_uid, has_gid(false); + + const auto found_uid = p->credentials_.find(its_uid); + has_uid = (found_uid != p->credentials_.end()); + if (has_uid) { + const auto found_gid = found_uid->second.find(its_gid); + has_gid = (found_gid != found_uid->second.end()); + } + + has_id = (has_uid && has_gid); + + if ((has_id && p->allow_who_) || (!has_id && !p->allow_who_)) { + if (!store_client_to_sec_client_mapping(_client, _sec_client)) { + std::string security_mode_text = "!"; + if (!check_credentials_) { + security_mode_text = " but will be allowed due to audit mode is active!"; + } + VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client + << " with UID/GID=" << std::dec << its_uid << "/" << its_gid + << " : Check credentials failed as existing credentials would be overwritten" + << security_mode_text; + return !check_credentials_; + } + store_sec_client_to_client_mapping(_sec_client, _client); + return true; + } + } + + std::string security_mode_text = " ~> Skip!"; + if (!check_credentials_) { + security_mode_text = " but will be allowed due to audit mode is active!"; + } + VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client + << " with UID/GID=" << std::dec << its_uid << "/" << its_gid + << " : Check credentials failed" << security_mode_text; + + return !check_credentials_; +#endif // VSOMEIP_DISABLE_SECURITY +} + +bool +policy_manager_impl::check_routing_credentials( + const vsomeip_sec_client_t *_sec_client) const { + +#ifdef VSOMEIP_DISABLE_SECURITY + (void)_sec_client; + + return (true); +#else + uid_t its_uid(0); + gid_t its_gid(0); + bool is_known_uid_gid(false); + + std::lock_guard its_lock(routing_credentials_mutex_); + if (_sec_client && _sec_client->client_type == VSOMEIP_CLIENT_UDS) { + its_uid = _sec_client->client.uds_client.user; + its_gid = _sec_client->client.uds_client.group; + + if (routing_credentials_.first == its_uid + && routing_credentials_.second == its_gid) { + + return (true); + } + + is_known_uid_gid = true; + } + + std::string security_mode_text = "!"; + if (!check_routing_credentials_) { + + security_mode_text = " but will be allowed due to audit mode is active!"; + } + + VSOMEIP_INFO << "vSomeIP Security: UID/GID=" + << (is_known_uid_gid ? std::to_string(its_uid) : "n/a") + << "." + << (is_known_uid_gid ? std::to_string(its_gid) : "n/a") + << " : Check routing credentials failed as " + << "configured routing manager credentials " + << "do not match with routing manager credentials" + << security_mode_text; + + return (!check_routing_credentials_); +#endif // VSOMEIP_DISABLE_SECURITY +} + +void +policy_manager_impl::set_routing_credentials(uint32_t _uid, uint32_t _gid, + const std::string &_name) { + + if (is_configured_) { + VSOMEIP_WARNING << "vSomeIP Security: Multiple definitions of routing-credentials." + << " Ignoring definition from " << _name; + } else { + routing_credentials_ = std::make_pair(_uid, _gid); + is_configured_ = true; + } +} + +bool +policy_manager_impl::is_client_allowed(const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance, method_t _method, + bool _is_request_service) const { + +#ifdef VSOMEIP_DISABLE_SECURITY + (void)_sec_client; + (void)_service; + (void)_instance; + (void)_method; + (void)_is_request_service; + + return (true); +#else + if (!policy_enabled_) { + return true; + } + + uid_t its_uid(ANY_UID); + gid_t its_gid(ANY_GID); + if (_sec_client) { + if (_sec_client->client_type == VSOMEIP_CLIENT_UDS) { + its_uid = _sec_client->client.uds_client.user; + its_gid = _sec_client->client.uds_client.group; + } else { + return true; + } + } else { + std::string security_mode_text = " ~> Skip!"; + if (!check_credentials_) { + security_mode_text = " but will be allowed due to audit mode is active!"; + } + VSOMEIP_INFO << "vSomeIP Security: uid/gid " + << std::dec << its_uid << "/" << its_gid << " is not valid." + << "Therefore it isn't allowed to communicate to service/instance " + << _service << "/" << _instance + << security_mode_text; + + return (!check_credentials_); + } + + // Check cache + auto its_credentials = std::make_pair(its_uid, its_gid); + auto its_key = std::make_tuple(_service, _instance, _method); + { + boost::shared_lock its_cache_lock(is_client_allowed_cache_mutex_); + const auto its_iter = is_client_allowed_cache_.find(its_credentials); + if (its_iter != is_client_allowed_cache_.end()) { + if (its_iter->second.find(its_key) != its_iter->second.end()) { + return (true); + } + } + } + + + // Check policies + boost::shared_lock its_lock(any_client_policies_mutex_); + for (const auto &p : any_client_policies_) { + std::lock_guard its_policy_lock(p->mutex_); + bool has_uid, has_gid(false); + bool is_matching(false); + + const auto found_uid = p->credentials_.find(its_uid); + has_uid = (found_uid != p->credentials_.end()); + if (has_uid) { + const auto found_gid = found_uid->second.find(its_gid); + has_gid = (found_gid != found_uid->second.end()); + } + + const auto found_service = p->requests_.find(_service); + if (found_service != p->requests_.end()) { + const auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + if (!_is_request_service) { + const auto found_method = found_instance->second.find(_method); + is_matching = (found_method != found_instance->second.end()); + } else { + // handle VSOMEIP_REQUEST_SERVICE + is_matching = true; + } + } + } + + if ((has_uid && has_gid && p->allow_who_) || ((!has_uid || !has_gid) && !p->allow_who_)) { + if (p->allow_what_) { + // allow policy + if (is_matching) { + boost::unique_lock its_cache_lock(is_client_allowed_cache_mutex_); + is_client_allowed_cache_[its_credentials].insert(its_key); + return (true); + } + } else { + // deny policy + // allow client if the service / instance / !ANY_METHOD was not found + if ((!is_matching && (_method != ANY_METHOD)) + // allow client if the service / instance / ANY_METHOD was not found + // and it is a "deny nothing" policy + || (!is_matching && (_method == ANY_METHOD) && p->requests_.empty())) { + boost::unique_lock its_cache_lock(is_client_allowed_cache_mutex_); + is_client_allowed_cache_[its_credentials].insert(its_key); + return (true); + } + } + } + } + + std::string security_mode_text = " ~> Skip!"; + if (!check_credentials_) { + security_mode_text = " but will be allowed due to audit mode is active!"; + } + + VSOMEIP_INFO << "vSomeIP Security: UID/GID=" + << std::dec << its_uid << "/" << its_gid + << " : Isn't allowed to communicate with service/instance/(method / event) " + << std::hex << _service << "/" << _instance << "/" << _method + << security_mode_text; + + return (!check_credentials_); +#endif // VSOMEIP_DISABLE_SECURITY +} + +bool +policy_manager_impl::is_offer_allowed(const vsomeip_sec_client_t *_sec_client, + service_t _service, instance_t _instance) const { + +#ifdef VSOMEIP_DISABLE_SECURITY + (void)_sec_client; + (void)_service; + (void)_instance; + + return (true); +#else + if (!policy_enabled_) + return true; + + uint32_t its_uid(ANY_UID), its_gid(ANY_GID); + if (_sec_client) { + if (_sec_client->client_type == VSOMEIP_CLIENT_UDS) { + its_uid = _sec_client->client.uds_client.user; + its_gid = _sec_client->client.uds_client.group; + } else { + return true; + } + } else { + std::string security_mode_text = " ~> Skip offer!"; + if (!check_credentials_) { + security_mode_text = " but will be allowed due to audit mode is active!"; + } + VSOMEIP_INFO << "vSomeIP Security: uid/gid " + << std::dec << its_uid << "/" << its_gid << " is not valid." + << "Therefore it isn't allowed to offer service/instance " + << _service << "/" << _instance + << security_mode_text; + + return (!check_credentials_); + } + + boost::shared_lock its_lock(any_client_policies_mutex_); + for (const auto &p : any_client_policies_) { + std::lock_guard its_policy_lock(p->mutex_); + bool has_uid, has_gid(false), has_offer(false); + + const auto found_uid = p->credentials_.find(its_uid); + has_uid = (found_uid != p->credentials_.end()); + if (has_uid) { + const auto found_gid = found_uid->second.find(its_gid); + has_gid = (found_gid != found_uid->second.end()); + } + + const auto found_service = p->offers_.find(_service); + if (found_service != p->offers_.end()) { + const auto found_instance = found_service->second.find(_instance); + has_offer = (found_instance != found_service->second.end()); + } + + if ((has_uid && has_gid && p->allow_who_) + || ((!has_uid || !has_gid) && !p->allow_who_)) { + if (p->allow_what_ == has_offer) { + return (true); + } + } + } + + std::string security_mode_text = " ~> Skip offer!"; + if (!check_credentials_) { + security_mode_text = " but will be allowed due to audit mode is active!"; + } + + VSOMEIP_INFO << "vSomeIP Security: UID/GID=" + << std::dec << its_uid << "/" << its_gid + << " isn't allowed to offer service/instance " + << std::hex << _service << "/" << _instance + << security_mode_text; + + return (!check_credentials_); +#endif // VSOMEIP_DISABLE_SECURITY +} + +#ifndef VSOMEIP_DISABLE_SECURITY +void +policy_manager_impl::load(const configuration_element &_element, const bool _lazy_load) { + + load_policies(_element); + if (!_lazy_load) { + + load_security_update_whitelist(_element); + load_security_policy_extensions(_element); + load_routing_credentials(_element); + + if (policy_enabled_ && check_credentials_) + VSOMEIP_INFO << "Security configuration is active."; + + if (policy_enabled_ && !check_credentials_) + VSOMEIP_INFO << "Security configuration is active but in audit mode (allow all)"; + } +} + +bool +policy_manager_impl::remove_security_policy(uint32_t _uid, uint32_t _gid) { + boost::unique_lock its_lock(any_client_policies_mutex_); + bool was_removed(false); + if (!any_client_policies_.empty()) { + std::vector>::iterator p_it = any_client_policies_.begin(); + while (p_it != any_client_policies_.end()) { + bool is_matching(false); + { + std::lock_guard its_policy_lock((*p_it)->mutex_); + bool has_uid(false), has_gid(false); + const auto found_uid = (*p_it)->credentials_.find(_uid); + has_uid = (found_uid != (*p_it)->credentials_.end()); + if (has_uid) { + const auto found_gid = found_uid->second.find(_gid); + has_gid = (found_gid != found_uid->second.end()); + } + + // only remove "credentials allow" policies to prevent removal of + // blacklist configured in file + if (has_uid && has_gid && (*p_it)->allow_who_) { + is_matching = true; + } + } + if (is_matching) { + was_removed = true; + p_it = any_client_policies_.erase(p_it); + } else { + ++p_it; + } + + boost::unique_lock its_cache_lock(is_client_allowed_cache_mutex_); + is_client_allowed_cache_.erase(std::make_pair(_uid, _gid)); + } + } + return (was_removed); +} + +void +policy_manager_impl::update_security_policy(uint32_t _uid, uint32_t _gid, + const std::shared_ptr &_policy) { + + boost::unique_lock its_lock(any_client_policies_mutex_); + std::shared_ptr its_matching_policy; + for (auto p : any_client_policies_) { + std::lock_guard its_guard(p->mutex_); + if (p->credentials_.size() == 1) { + const auto its_uids = *(p->credentials_.begin()); + if (its_uids.first.lower() == _uid + && its_uids.first.upper() == _uid) { + if (its_uids.second.size() == 1) { + const auto its_gids = *(its_uids.second.begin()); + if (its_gids.lower() == _gid + && its_gids.upper() == _gid) { + if (p->allow_who_ == _policy->allow_who_) { + its_matching_policy = p; + break; + } + } + } + } + } + } + + if (its_matching_policy) { + std::lock_guard its_guard{its_matching_policy->mutex_}; + for (const auto &r : _policy->requests_) { + service_t its_lower, its_upper; + get_bounds(r.first, its_lower, its_upper); + for (auto s = its_lower; s <= its_upper; s++) { + boost::icl::discrete_interval its_service(s, s, + boost::icl::interval_bounds::closed()); + its_matching_policy->requests_ += std::make_pair(its_service, r.second); + } + } + for (const auto &o : _policy->offers_) { + service_t its_lower, its_upper; + get_bounds(o.first, its_lower, its_upper); + for (auto s = its_lower; s <= its_upper; s++) { + boost::icl::discrete_interval its_service(s, s, + boost::icl::interval_bounds::closed()); + its_matching_policy->offers_ += std::make_pair(its_service, o.second); + } + } + } else { + any_client_policies_.push_back(_policy); + } + + boost::unique_lock its_cache_lock(is_client_allowed_cache_mutex_); + is_client_allowed_cache_.erase(std::make_pair(_uid, _gid)); +} + +void +policy_manager_impl::add_security_credentials(uint32_t _uid, uint32_t _gid, + const std::shared_ptr &_policy, client_t _client) { + + bool was_found(false); + boost::unique_lock its_lock(any_client_policies_mutex_); + for (const auto &p : any_client_policies_) { + bool has_uid(false), has_gid(false); + + std::lock_guard its_policy_lock(p->mutex_); + const auto found_uid = p->credentials_.find(_uid); + has_uid = (found_uid != p->credentials_.end()); + if (has_uid) { + const auto found_gid = found_uid->second.find(_gid); + has_gid = (found_gid != found_uid->second.end()); + } + + if (has_uid && has_gid && p->allow_who_) { + was_found = true; + break; + } + } + + // Do not add the new (credentials-only-policy) if a allow + // credentials policy with same credentials was found + if (!was_found) { + any_client_policies_.push_back(_policy); + VSOMEIP_INFO << __func__ << " Added security credentials at client: 0x" + << std::hex << _client << std::dec << " with UID: " << _uid << " GID: " << _gid; + } +} + +bool +policy_manager_impl::is_policy_update_allowed(uint32_t _uid, std::shared_ptr &_policy) const { + + bool is_uid_allowed(false); + { + std::lock_guard its_lock(uid_whitelist_mutex_); + const auto found_uid = uid_whitelist_.find(_uid); + is_uid_allowed = (found_uid != uid_whitelist_.end()); + } + + if (is_uid_allowed && _policy) { + std::lock_guard its_lock(service_interface_whitelist_mutex_); + std::lock_guard its_policy_lock(_policy->mutex_); + for (const auto &its_request : _policy->requests_) { + bool has_service(false); + + service_t its_service(0); + for (its_service = its_request.first.lower(); + its_service <= its_request.first.upper(); + its_service++) { + + const auto found_service = service_interface_whitelist_.find(its_service); + has_service = (found_service != service_interface_whitelist_.end()); + if (!has_service) + break; + } + + if (!has_service) { + if (!check_whitelist_) { + VSOMEIP_INFO << "vSomeIP Security: Policy update requesting service ID: " + << std::hex << its_service + << " is not allowed, but will be allowed due to whitelist audit mode is active!"; + } else { + VSOMEIP_WARNING << "vSomeIP Security: Policy update requesting service ID: " + << std::hex << its_service + << " is not allowed! -> ignore update"; + } + return (!check_whitelist_); + } + } + return (true); + } else { + if (!check_whitelist_) { + VSOMEIP_INFO << "vSomeIP Security: Policy update for UID: " << std::dec << _uid + << " is not allowed, but will be allowed due to whitelist audit mode is active!"; + } else { + VSOMEIP_WARNING << "vSomeIP Security: Policy update for UID: " << std::dec << _uid + << " is not allowed! -> ignore update"; + } + return (!check_whitelist_); + } +} + +bool +policy_manager_impl::is_policy_removal_allowed(uint32_t _uid) const { + std::lock_guard its_lock(uid_whitelist_mutex_); + for (auto its_uid_range : uid_whitelist_) { + if (its_uid_range.lower() <= _uid && _uid <= its_uid_range.upper()) { + return (true); + } + } + + if (!check_whitelist_) { + VSOMEIP_INFO << "vSomeIP Security: Policy removal for UID: " + << std::dec << _uid + << " is not allowed, but will be allowed due to whitelist audit mode is active!"; + } else { + VSOMEIP_WARNING << "vSomeIP Security: Policy removal for UID: " + << std::dec << _uid + << " is not allowed! -> ignore removal"; + } + return (!check_whitelist_); +} + +bool +policy_manager_impl::parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, + uint32_t &_uid, uint32_t &_gid, const std::shared_ptr &_policy) const { + + bool is_valid = _policy->deserialize(_buffer, _buffer_size); + if (is_valid) + is_valid = _policy->get_uid_gid(_uid, _gid); + return is_valid; +} + +/////////////////////////////////////////////////////////////////////////////// +// Configuration +/////////////////////////////////////////////////////////////////////////////// +void +policy_manager_impl::load_policies(const configuration_element &_element) { +#ifdef _WIN32 + return; +#endif + try { + auto optional = _element.tree_.get_child_optional("security"); + if (!optional) { + return; + } + policy_enabled_ = true; + auto found_policy = _element.tree_.get_child("security"); + for (auto its_security = found_policy.begin(); + its_security != found_policy.end(); ++its_security) { + if (its_security->first == "check_credentials") { + if (its_security->second.data() == "true") { + check_credentials_ = true; + } else { + check_credentials_ = false; + } + } else if (its_security->first == "allow_remote_clients") { + if (its_security->second.data() == "true") { + allow_remote_clients_ = true; + } else { + allow_remote_clients_ = false; + } + } else if (its_security->first == "policies") { + for (auto its_policy = its_security->second.begin(); + its_policy != its_security->second.end(); ++its_policy) { + load_policy(its_policy->second); + } + } + } + } catch (...) { + } +} + +void +policy_manager_impl::load_policy(const boost::property_tree::ptree &_tree) { + + std::shared_ptr policy(std::make_shared()); + bool allow_deny_set(false); + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + if (i->first == "credentials") { + boost::icl::interval_set its_uid_interval_set; + boost::icl::interval_set its_gid_interval_set; + boost::icl::discrete_interval its_uid_interval; + boost::icl::discrete_interval its_gid_interval; + + bool has_uid(false), has_gid(false); + bool has_uid_range(false), has_gid_range(false); + for (auto n = i->second.begin(); + n != i->second.end(); ++n) { + std::string its_key(n->first); + std::string its_value(n->second.data()); + if (its_key == "uid") { + if(n->second.data().empty()) { + load_interval_set(n->second, its_uid_interval_set); + has_uid_range = true; + } else { + if (its_value != "any") { + uint32_t its_uid; + read_data(its_value, its_uid); + its_uid_interval = boost::icl::construct< + boost::icl::discrete_interval >( + its_uid, its_uid, + boost::icl::interval_bounds::closed()); + } else { + its_uid_interval = boost::icl::construct< + boost::icl::discrete_interval >( + std::numeric_limits::min(), + std::numeric_limits::max(), + boost::icl::interval_bounds::closed()); + } + has_uid = true; + } + } else if (its_key == "gid") { + if(n->second.data().empty()) { + load_interval_set(n->second, its_gid_interval_set); + has_gid_range = true; + } else { + if (its_value != "any") { + uint32_t its_gid; + read_data(its_value, its_gid); + its_gid_interval = boost::icl::construct< + boost::icl::discrete_interval >( + its_gid, its_gid, + boost::icl::interval_bounds::closed()); + } else { + its_gid_interval = boost::icl::construct< + boost::icl::discrete_interval >( + std::numeric_limits::min(), + std::numeric_limits::max(), + boost::icl::interval_bounds::closed()); + } + has_gid = true; + } + } else if (its_key == "allow" || its_key == "deny") { + policy->allow_who_ = (its_key == "allow"); + load_credential(n->second, policy->credentials_); + } + } + + if (has_uid && has_gid) { + its_gid_interval_set.insert(its_gid_interval); + + policy->credentials_ += std::make_pair(its_uid_interval, its_gid_interval_set); + policy->allow_who_ = true; + } + if (has_uid_range && has_gid_range) { + for (const auto u : its_uid_interval_set) + policy->credentials_ += std::make_pair(u, its_gid_interval_set); + policy->allow_who_ = true; + } + } else if (i->first == "allow") { + if (allow_deny_set) { + VSOMEIP_WARNING << "vSomeIP Security: Security configuration: \"allow\" tag overrides " + << "already set \"deny\" tag. " + << "Either \"deny\" or \"allow\" is allowed."; + } + allow_deny_set = true; + policy->allow_what_ = true; + load_policy_body(policy, i); + } else if (i->first == "deny") { + if (allow_deny_set) { + VSOMEIP_WARNING << "vSomeIP Security: Security configuration: \"deny\" tag overrides " + << "already set \"allow\" tag. " + << "Either \"deny\" or \"allow\" is allowed."; + } + allow_deny_set = true; + policy->allow_what_ = false; + load_policy_body(policy, i); + } + } + boost::unique_lock its_lock(any_client_policies_mutex_); + any_client_policies_.push_back(policy); +} + +void +policy_manager_impl::load_policy_body(std::shared_ptr &_policy, + const boost::property_tree::ptree::const_iterator &_tree) { + + for (auto l = _tree->second.begin(); l != _tree->second.end(); ++l) { + if (l->first == "requests") { + for (auto n = l->second.begin(); n != l->second.end(); ++n) { + service_t its_service = 0x0; + instance_t its_instance = 0x0; + boost::icl::interval_map > its_instance_method_intervals; + for (auto k = n->second.begin(); k != n->second.end(); ++k) { + if (k->first == "service") { + read_data(k->second.data(), its_service); + } else if (k->first == "instance") { // legacy definition for instances + boost::icl::interval_set its_instance_interval_set; + boost::icl::interval_set its_method_interval_set; + boost::icl::discrete_interval all_instances(0x01, 0xFFFF, + boost::icl::interval_bounds::closed()); + boost::icl::discrete_interval all_methods(0x01, 0xFFFF, + boost::icl::interval_bounds::closed()); + + std::string its_value(k->second.data()); + if (its_value != "any") { + read_data(its_value, its_instance); + if (its_instance != 0x0) { + its_instance_interval_set.insert(its_instance); + its_method_interval_set.insert(all_methods); + } + } else { + its_instance_interval_set.insert(all_instances); + its_method_interval_set.insert(all_methods); + } + for (const auto i : its_instance_interval_set) { + its_instance_method_intervals + += std::make_pair(i, its_method_interval_set); + } + } else if (k->first == "instances") { // new instances definition + for (auto p = k->second.begin(); p != k->second.end(); ++p) { + boost::icl::interval_set its_instance_interval_set; + boost::icl::interval_set its_method_interval_set; + boost::icl::discrete_interval all_methods(0x01, 0xFFFF, + boost::icl::interval_bounds::closed()); + for (auto m = p->second.begin(); m != p->second.end(); ++m) { + if (m->first == "ids") { + load_interval_set(m->second, its_instance_interval_set); + } else if (m->first == "methods") { + load_interval_set(m->second, its_method_interval_set); + } + } + if (its_method_interval_set.empty()) + its_method_interval_set.insert(all_methods); + for (const auto i : its_instance_interval_set) { + its_instance_method_intervals + += std::make_pair(i, its_method_interval_set); + } + } + + if (its_instance_method_intervals.empty()) { + boost::icl::interval_set its_legacy_instance_interval_set; + boost::icl::interval_set its_legacy_method_interval_set; + boost::icl::discrete_interval all_methods(0x01, 0xFFFF, + boost::icl::interval_bounds::closed()); + its_legacy_method_interval_set.insert(all_methods); + + // try to only load instance ranges with any method to be allowed + load_interval_set(k->second, its_legacy_instance_interval_set); + for (const auto i : its_legacy_instance_interval_set) { + its_instance_method_intervals + += std::make_pair(i, its_legacy_method_interval_set); + } + } + } + } + if (its_service != 0x0 && !its_instance_method_intervals.empty()) { + _policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + its_service, its_service, + boost::icl::interval_bounds::closed()), + its_instance_method_intervals); + } + } + } else if (l->first == "offers") { + for (auto n = l->second.begin(); n != l->second.end(); ++n) { + service_t its_service(0x0); + instance_t its_instance(0x0); + boost::icl::interval_set its_instance_interval_set; + for (auto k = n->second.begin(); k != n->second.end(); ++k) { + if (k->first == "service") { + read_data(k->second.data(), its_service); + } else if (k->first == "instance") { // legacy definition for instances + std::string its_value(k->second.data()); + if (its_value != "any") { + read_data(its_value, its_instance); + if (its_instance != 0x0) { + its_instance_interval_set.insert(its_instance); + } + } else { + its_instance_interval_set.insert( + boost::icl::discrete_interval( + 0x0001, 0xFFFF)); + } + } else if (k->first == "instances") { // new instances definition + load_interval_set(k->second, its_instance_interval_set); + } + } + if (its_service != 0x0 && !its_instance_interval_set.empty()) { + _policy->offers_ + += std::make_pair( + boost::icl::discrete_interval( + its_service, its_service, + boost::icl::interval_bounds::closed()), + its_instance_interval_set); + } + } + } + } +} + + +void +policy_manager_impl::load_credential( + const boost::property_tree::ptree &_tree, + boost::icl::interval_map > &_credentials) { + + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + boost::icl::interval_set its_uid_interval_set; + boost::icl::interval_set its_gid_interval_set; + + for (auto j = i->second.begin(); j != i->second.end(); ++j) { + std::string its_key(j->first); + if (its_key == "uid") { + load_interval_set(j->second, its_uid_interval_set); + } else if (its_key == "gid") { + load_interval_set(j->second, its_gid_interval_set); + } else { + VSOMEIP_WARNING << "vSomeIP Security: Security configuration: " + << "Malformed credential (contains illegal key \"" + << its_key << "\")"; + } + } + + for (const auto its_uid_interval : its_uid_interval_set) { + _credentials + += std::make_pair(its_uid_interval, its_gid_interval_set); + } + } +} + +bool +policy_manager_impl::load_routing_credentials(const configuration_element &_element) { + try { + auto its_routing_cred = _element.tree_.get_child("routing-credentials"); + if (is_configured_) { + VSOMEIP_WARNING << "vSomeIP Security: Multiple definitions of routing-credentials." + << " Ignoring definition from " << _element.name_; + } else { + for (auto i = its_routing_cred.begin(); + i != its_routing_cred.end(); + ++i) { + std::string its_key(i->first); + std::string its_value(i->second.data()); + if (its_key == "uid") { + uint32_t its_uid(0); + read_data(its_value, its_uid); + std::lock_guard its_lock(routing_credentials_mutex_); + std::get<0>(routing_credentials_) = its_uid; + } else if (its_key == "gid") { + uint32_t its_gid(0); + read_data(its_value, its_gid); + std::lock_guard its_lock(routing_credentials_mutex_); + std::get<1>(routing_credentials_) = its_gid; + } + } + check_routing_credentials_ = true; + is_configured_ = true; + } + } catch (...) { + return false; + } + return true; +} + + +void +policy_manager_impl::load_security_update_whitelist(const configuration_element &_element) { +#ifdef _WIN32 + return; +#endif + try { + auto optional = _element.tree_.get_child_optional("security-update-whitelist"); + if (!optional) { + return; + } + auto found_whitelist = _element.tree_.get_child("security-update-whitelist"); + for (auto its_whitelist = found_whitelist.begin(); + its_whitelist != found_whitelist.end(); ++its_whitelist) { + + if (its_whitelist->first == "uids") { + { + std::lock_guard its_lock(uid_whitelist_mutex_); + load_interval_set(its_whitelist->second, uid_whitelist_); + } + } else if (its_whitelist->first == "services") { + { + std::lock_guard its_lock(service_interface_whitelist_mutex_); + load_interval_set(its_whitelist->second, service_interface_whitelist_); + } + } else if (its_whitelist->first == "check-whitelist") { + if (its_whitelist->second.data() == "true") { + check_whitelist_ = true; + } else { + check_whitelist_ = false; + } + } + } + } catch (...) { + } +} + +void +policy_manager_impl::load_security_policy_extensions(const configuration_element &_element) { +#ifdef _WIN32 + return; +#endif + try { + auto optional = _element.tree_.get_child_optional("container_policy_extensions"); + if (!optional) { + return; + } + auto found_policy_extensions = _element.tree_.get_child("container_policy_extensions"); + boost::filesystem::path its_base_path; + { + boost::unique_lock its_lock(policy_extension_paths_mutex_); + its_base_path = boost::filesystem::path(policy_base_path_); + } + + for (auto i = found_policy_extensions.begin(); + i != found_policy_extensions.end(); ++i) { + boost::filesystem::path its_canonical_path; + std::string its_client_host(""); + std::string its_path(""); + auto its_data = i->second; + for (auto j = its_data.begin(); j != its_data.end(); ++j) { + std::string its_key(j->first); + std::string its_value(j->second.data()); + if (its_key == "container") { + if(its_value != "") { + its_client_host = its_value; + } + } else if (its_key == "path") { + if(its_value != "") { + its_path = its_value; + } + } + } + + std::string str = VSOMEIP_DEFAULT_CONFIGURATION_FOLDER; + std::string its_filesystem_path = str.substr(0, str.find_last_of("\\/")) + + its_path.erase(0, its_path.find_first_of("\\/")); + + if (!utility::is_folder(its_filesystem_path)) { + VSOMEIP_DEBUG << __func__ << ": The path " + << its_filesystem_path + << " is not valid"; + } + std::map empty_map; + policy_extension_paths_[its_client_host] = std::make_pair(its_filesystem_path, empty_map); + + VSOMEIP_INFO << __func__ << ": Insert policy extension path: [" << its_filesystem_path + << "] for hostname: [" << its_client_host << "]"; + } + } catch (...) { + } +} + +template +void policy_manager_impl::load_interval_set( + const boost::property_tree::ptree &_tree, + boost::icl::interval_set &_intervals, bool _exclude_margins) { + + boost::icl::interval_set its_intervals; + T_ its_min = std::numeric_limits::min(); + T_ its_max = std::numeric_limits::max(); + + if (_exclude_margins) { + its_min++; + its_max--; + } + + const std::string its_key(_tree.data()); + if (its_key == "any") { + its_intervals.insert(boost::icl::discrete_interval::closed( + its_min, its_max)); + } else { + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + auto its_data = i->second; + if (!its_data.data().empty()) { + T_ its_id; + read_data(its_data.data(), its_id); + if (its_id >= its_min && its_id <= its_max) + its_intervals.insert(its_id); + } else { + T_ its_first, its_last; + bool has_first(false), has_last(false); + for (auto j = its_data.begin(); j != its_data.end(); ++j) { + std::string its_key(j->first); + std::string its_value(j->second.data()); + if (its_key == "first") { + if (its_value == "min") { + its_first = its_min; + } else { + read_data(its_value, its_first); + } + has_first = true; + } else if (its_key == "last") { + if (its_value == "max") { + its_last = its_max; + } else { + read_data(its_value, its_last); + } + has_last = true; + } else { + VSOMEIP_WARNING << "vSomeIP Security: Security configuration: " + << " Malformed range. Contains illegal key (" + << its_key << ")"; + } + } + if (has_first && has_last && its_first <= its_last) { + its_intervals.insert( + boost::icl::discrete_interval::closed(its_first, its_last)); + } + } + } + } + + _intervals = its_intervals; +} + +void +policy_manager_impl::get_requester_policies(const std::shared_ptr _policy, + std::set > &_requesters) const { + + std::lock_guard its_lock(_policy->mutex_); + for (const auto &o : _policy->offers_) { + boost::unique_lock its_policies_lock(any_client_policies_mutex_); + for (const auto &p : any_client_policies_) { + if (p == _policy) + continue; + + std::lock_guard its_lock(p->mutex_); + + auto its_policy = std::make_shared(); + its_policy->credentials_ = p->credentials_; + + for (const auto &r : p->requests_) { + // o represents an offer by a service interval and its instances + // (a set of intervals) + // r represents a request by a service interval and its instances + // and methods (instance intervals mapped to interval sets of methods) + // + // Thus, r matches o if their service identifiers as well as their + // instances overlap. If r and o match, a new policy must be + // created that contains the overlapping services/instances mapping + // of r and o together with the methods from r + service_t its_o_lower, its_o_upper, its_r_lower, its_r_upper; + get_bounds(o.first, its_o_lower, its_o_upper); + get_bounds(r.first, its_r_lower, its_r_upper); + + if (its_o_lower <= its_r_upper && its_r_lower <= its_o_upper) { + auto its_service_min = std::max(its_o_lower, its_r_lower); + auto its_service_max = std::min(its_r_upper, its_o_upper); + + for (const auto &i : o.second) { + for (const auto &j : r.second) { + for (const auto &k : j.second) { + instance_t its_i_lower, its_i_upper, its_k_lower, its_k_upper; + get_bounds(i, its_i_lower, its_i_upper); + get_bounds(k, its_k_lower, its_k_upper); + + if (its_i_lower <= its_k_upper && its_k_lower <= its_i_upper) { + auto its_instance_min = std::max(its_i_lower, its_k_lower); + auto its_instance_max = std::min(its_i_upper, its_k_upper); + + boost::icl::interval_map > its_instances_methods; + its_instances_methods += std::make_pair( + boost::icl::interval::closed( + its_instance_min, its_instance_max), + j.second); + + its_policy->requests_ += std::make_pair( + boost::icl::interval::closed( + its_service_min, its_service_max), + its_instances_methods); + } + } + } + } + } + } + + if (!its_policy->requests_.empty()) { + _requesters.insert(its_policy); + its_policy->print(); + } + } + } +} + +void +policy_manager_impl::get_clients(uid_t _uid, gid_t _gid, + std::unordered_set &_clients) const { + + std::lock_guard its_lock(ids_mutex_); + for (const auto &i : ids_) { + if (i.second.client_type == VSOMEIP_CLIENT_UDS + && i.second.client.uds_client.user == _uid + && i.second.client.uds_client.group == _gid) + _clients.insert(i.first); + } +} + +bool +policy_manager_impl::is_policy_extension(const std::string &_path) const { + auto its_pos = _path.find("vsomeip_policy_extensions.json"); + if (its_pos != std::string::npos) { + return true; + } + return false; +} + +void +policy_manager_impl::set_policy_extension_base_path(const std::string &_path) { + auto its_pos = _path.find("vsomeip_policy_extensions.json"); + std::lock_guard its_lock(policy_base_path_mutex_); + policy_base_path_ = _path.substr(0, its_pos); +} + +std::string +policy_manager_impl::get_policy_extension_path(const std::string &_client_host) const { + boost::shared_lock lock(policy_extension_paths_mutex_); + return get_policy_extension_path_unlocked(_client_host); +} +//only be called after loading of the mutex +std::string +policy_manager_impl::get_policy_extension_path_unlocked(const std::string &_client_host) const { + std::string its_path(""); + + auto found_host = policy_extension_paths_.find(_client_host); + + if (found_host != policy_extension_paths_.end()) { + its_path = found_host->second.first; + } + return its_path; +} + +policy_manager_impl::policy_loaded_e +policy_manager_impl::is_policy_extension_loaded(const std::string &_client_host) const { + boost::shared_lock lock(policy_extension_paths_mutex_); + + auto found_host = policy_extension_paths_.find(_client_host); + if (found_host != policy_extension_paths_.end()) { + + auto found_complete_path = found_host->second.second.find( + get_security_config_folder(found_host->second.first)); + if (found_complete_path != found_host->second.second.end()) { + if (found_complete_path->second) { + return policy_manager_impl::policy_loaded_e::POLICY_PATH_FOUND_AND_LOADED; + } else { + return policy_manager_impl::policy_loaded_e::POLICY_PATH_FOUND_AND_NOT_LOADED; + } + } + } + + // we do not have a path to load + return policy_manager_impl::policy_loaded_e::POLICY_PATH_INEXISTENT; +} + +void +policy_manager_impl::set_is_policy_extension_loaded(const std::string &_client_host, + const bool _loaded) { + boost::unique_lock lock(policy_extension_paths_mutex_); + auto found_host = policy_extension_paths_.find(_client_host); + + if (found_host != policy_extension_paths_.end()) { + std::string its_folder = get_policy_extension_path_unlocked(_client_host); + std::string its_complete_folder = get_security_config_folder(its_folder); + + // if the map key of complete path folder exist, will be updated + // if not will create an new entry + found_host->second.second[its_complete_folder] = _loaded; + } +} + +std::string +policy_manager_impl::get_security_config_folder(const std::string &its_folder) const +{ + std::stringstream its_security_config_folder; + its_security_config_folder << its_folder; + +#if defined(__linux__) || defined(ANDROID) + its_security_config_folder << "/" << getuid() << "_" << getgid(); +#endif + + if (utility::is_folder(its_security_config_folder.str())) { + return its_security_config_folder.str(); + } else { + VSOMEIP_INFO << __func__<< ": Invalid folder for " << its_security_config_folder.str(); + } + return std::string(""); } std::shared_ptr @@ -33,29 +1299,175 @@ policy_manager_impl::parse_uid_gid(const byte_t* &_buffer, && its_policy->deserialize_uid_gid(_buffer, _buffer_size, _uid, _gid)); } +#endif // !VSOMEIP_DISABLE_SECURITY + bool -policy_manager_impl::is_policy_update_allowed(uint32_t _uid, std::shared_ptr &_policy) const { +policy_manager_impl::store_client_to_sec_client_mapping( + client_t _client, const vsomeip_sec_client_t *_sec_client) { + + if (_sec_client != nullptr && _sec_client->client_type == VSOMEIP_CLIENT_UDS) { + // store the client -> sec_client mapping + std::lock_guard its_lock(ids_mutex_); + auto found_client = ids_.find(_client); + if (found_client != ids_.end()) { + if (!utility::compare(found_client->second, *_sec_client)) { + uid_t its_old_uid = found_client->second.client.uds_client.user; + gid_t its_old_gid = found_client->second.client.uds_client.group; + uid_t its_new_uid = _sec_client->client.uds_client.user; + gid_t its_new_gid = _sec_client->client.uds_client.group; + + VSOMEIP_WARNING << "vSomeIP Security: Client 0x" + << std::hex << _client << " with UID/GID=" + << std::dec << its_new_uid << "/" << its_new_gid + << " : Overwriting existing credentials UID/GID=" + << std::dec << its_old_uid << "/" << its_old_gid; - auto its_security = security_impl::get(); - return (its_security - && its_security->is_policy_update_allowed(_uid, _policy)); + found_client->second = *_sec_client; + return (true); + } + } else { + ids_[_client] = *_sec_client; + } + return (true); + } + + return (false); } bool -policy_manager_impl::is_policy_removal_allowed(uint32_t _uid) const { +policy_manager_impl::get_client_to_sec_client_mapping(client_t _client, + vsomeip_sec_client_t &_sec_client) { + { + // get the UID / GID of the client + std::lock_guard its_lock(ids_mutex_); + if (ids_.find(_client) != ids_.end()) { + _sec_client = ids_[_client]; + return (true); + } + return (false); + } +} - auto its_security = security_impl::get(); - return (its_security - && its_security->is_policy_removal_allowed(_uid)); +bool +policy_manager_impl::remove_client_to_sec_client_mapping(client_t _client) { + + vsomeip_sec_client_t its_sec_client; + bool is_client_removed(false); + bool is_sec_client_removed(false); + { + std::lock_guard its_lock(ids_mutex_); + auto found_client = ids_.find(_client); + if (found_client != ids_.end()) { + its_sec_client = found_client->second; + ids_.erase(found_client); + is_client_removed = true; + } + } + { + std::lock_guard its_lock(sec_client_to_clients_mutex_); + if (is_client_removed) { + auto found_sec_client = sec_client_to_clients_.find(its_sec_client); + if (found_sec_client != sec_client_to_clients_.end()) { + auto its_client = found_sec_client->second.find(_client); + if (its_client != found_sec_client->second.end()) { + found_sec_client->second.erase(its_client); + if (found_sec_client->second.empty()) { + sec_client_to_clients_.erase(found_sec_client); + } + is_sec_client_removed = true; + } + } + } else { + for (auto it = sec_client_to_clients_.begin(); + it != sec_client_to_clients_.end(); ++it) { + auto its_client = it->second.find(_client); + if (its_client != it->second.end()) { + it->second.erase(its_client); + if (it->second.empty()) { + sec_client_to_clients_.erase(it); + } + is_sec_client_removed = true; + break; + } + } + } + } + + return (is_client_removed && is_sec_client_removed); +} + +void +policy_manager_impl::store_sec_client_to_client_mapping( + const vsomeip_sec_client_t *_sec_client, client_t _client) { + + if (_sec_client && _sec_client->client_type == VSOMEIP_CLIENT_UDS) { + // store the uid gid to clients mapping + std::lock_guard its_lock(sec_client_to_clients_mutex_); + auto found_sec_client = sec_client_to_clients_.find(*_sec_client); + if (found_sec_client != sec_client_to_clients_.end()) { + found_sec_client->second.insert(_client); + } else { + std::set mapped_clients; + mapped_clients.insert(_client); + sec_client_to_clients_.insert(std::make_pair(*_sec_client, mapped_clients)); + } + } } bool -policy_manager_impl::parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, - uint32_t &_uid, uint32_t &_gid, const std::shared_ptr &_policy) const { +policy_manager_impl::get_sec_client_to_clients_mapping( + const vsomeip_sec_client_t *_sec_client, + std::set &_clients) { + + if (_sec_client && _sec_client->client_type == VSOMEIP_CLIENT_UDS) { + // get the clients corresponding to uid, gid + std::lock_guard its_lock(sec_client_to_clients_mutex_); + auto found_sec_client = sec_client_to_clients_.find(*_sec_client); + if (found_sec_client != sec_client_to_clients_.end()) { + _clients = found_sec_client->second; + return true; + } + } + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// Manage the security object +//////////////////////////////////////////////////////////////////////////////// +static std::shared_ptr *the_policy_manager_ptr__(nullptr); +static std::mutex the_policy_manager_mutex__; + +std::shared_ptr +policy_manager_impl::get() { +#if defined(__linux__) || defined(ANDROID) + std::lock_guard its_lock(the_policy_manager_mutex__); +#endif + if(the_policy_manager_ptr__ == nullptr) { + the_policy_manager_ptr__ = new std::shared_ptr(); + } + if (the_policy_manager_ptr__ != nullptr) { + if (!(*the_policy_manager_ptr__)) { + *the_policy_manager_ptr__ = std::make_shared(); + } + return (*the_policy_manager_ptr__); + } + return (nullptr); +} - auto its_security = security_impl::get(); - return (its_security - && its_security->parse_policy(_buffer, _buffer_size, _uid, _gid, _policy)); +#if defined(__linux__) || defined(ANDROID) +static void security_teardown(void) __attribute__((destructor)); +static void security_teardown(void) +{ + if (the_policy_manager_ptr__ != nullptr) { + // TODO: This mutex is causing a crash due to changes in the way mutexes are defined. + // Since this function only runs on the main thread, no mutex should be needed. Leaving a + // comment pending a refactor. + // std::lock_guard its_lock(the_policy_manager_mutex__); + the_policy_manager_ptr__->reset(); + delete the_policy_manager_ptr__; + the_policy_manager_ptr__ = nullptr; + } } +#endif } // namespace vsomeip_v3 diff --git a/implementation/security/src/security.cpp b/implementation/security/src/security.cpp index 7c7b3f4..e9a6381 100644 --- a/implementation/security/src/security.cpp +++ b/implementation/security/src/security.cpp @@ -1,15 +1,145 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../include/security_impl.hpp" +#include "../include/security.hpp" +#include "../include/policy_manager_impl.hpp" +#include +#ifdef ANDROID +#include "../../configuration/include/internal_android.hpp" +#else +#include "../../configuration/include/internal.hpp" +#endif +#include "../../plugin/include/plugin_manager.hpp" + +#include +#include + +#define VSOMEIP_SEC_SYMDEF(sym) symdef_t{\ + "vsomeip_sec_policy_"#sym, nullptr, reinterpret_cast(&sym) \ +} namespace vsomeip_v3 { +bool +security::load() { + using symdef_t = std::tuple; + std::array symbol_table{ + VSOMEIP_SEC_SYMDEF(initialize), + VSOMEIP_SEC_SYMDEF(authenticate_router), + VSOMEIP_SEC_SYMDEF(is_client_allowed_to_offer), + VSOMEIP_SEC_SYMDEF(is_client_allowed_to_request), + VSOMEIP_SEC_SYMDEF(is_client_allowed_to_access_member) + }; + + if (auto manager = plugin_manager::get()) { + if (auto lib = manager->load_library(VSOMEIP_SEC_LIBRARY)) { + // First we load the symbols into the 2nd tuple element + for (auto& symdef : symbol_table) { + auto name = std::get<0>(symdef); + auto& symbol = std::get<1>(symdef); + if (!(symbol = manager->load_symbol(lib, name))) { + VSOMEIP_ERROR << __func__ + << ": security library misses " + << std::quoted(name) + << " function."; + manager->unload_library(lib); + return false; + } + } + + // Now that we have all symbols loaded, + // assign the 2nd tuple element to the 3rd + for (auto& symdef : symbol_table) { + auto symbol = std::get<1>(symdef); + auto& stub = std::get<2>(symdef); + *stub = symbol; + } + + // Symbol loading complete, success! + return true; + } + } + + return false; +} + +decltype(security::initialize) +security::initialize = security::default_initialize; + +decltype(security::authenticate_router) +security::authenticate_router = security::default_authenticate_router; + +decltype(security::is_client_allowed_to_offer) +security::is_client_allowed_to_offer = security::default_is_client_allowed_to_offer; + +decltype(security::is_client_allowed_to_request) +security::is_client_allowed_to_request = security::default_is_client_allowed_to_request; + +decltype(security::is_client_allowed_to_access_member) +security::is_client_allowed_to_access_member = security::default_is_client_allowed_to_access_member; + +// +// Default interface implementation +// +vsomeip_sec_policy_result_t +security::default_initialize(void) { + return VSOMEIP_SEC_POLICY_OK; +} + +vsomeip_sec_acl_result_t +security::default_authenticate_router( + const vsomeip_sec_client_t *_server) { + if (_server && _server->client_type == VSOMEIP_CLIENT_TCP) + return VSOMEIP_SEC_OK; + + if (policy_manager_impl::get()->check_routing_credentials(_server)) + return VSOMEIP_SEC_OK; + else + return VSOMEIP_SEC_PERM_DENIED; +} + +vsomeip_sec_acl_result_t +security::default_is_client_allowed_to_offer( + const vsomeip_sec_client_t *_client, + vsomeip_sec_service_id_t _service, + vsomeip_sec_instance_id_t _instance) { + if (_client && _client->client_type == VSOMEIP_CLIENT_TCP) + return VSOMEIP_SEC_OK; + + if (policy_manager_impl::get()->is_offer_allowed(_client, _service, _instance)) + return VSOMEIP_SEC_OK; + else + return VSOMEIP_SEC_PERM_DENIED; +} + +vsomeip_sec_acl_result_t +security::default_is_client_allowed_to_request( + const vsomeip_sec_client_t *_client, + vsomeip_sec_service_id_t _service, + vsomeip_sec_instance_id_t _instance) { + if (_client && _client->client_type == VSOMEIP_CLIENT_TCP) + return VSOMEIP_SEC_OK; + + if (policy_manager_impl::get()->is_client_allowed(_client, _service, _instance, 0x00, true)) + return VSOMEIP_SEC_OK; + else + return VSOMEIP_SEC_PERM_DENIED; +} + +vsomeip_sec_acl_result_t +security::default_is_client_allowed_to_access_member( + const vsomeip_sec_client_t *_client, + vsomeip_sec_service_id_t _service, + vsomeip_sec_instance_id_t _instance, + vsomeip_sec_member_id_t _member) { + if (_client && _client->client_type == VSOMEIP_CLIENT_TCP) + return VSOMEIP_SEC_OK; -std::shared_ptr -security::get() { - return security_impl::get(); + if (policy_manager_impl::get()->is_client_allowed(_client, _service, _instance, _member, false)) + return VSOMEIP_SEC_OK; + else + return VSOMEIP_SEC_PERM_DENIED; } } // namespace vsomeip_v3 diff --git a/implementation/security/src/security_impl.cpp b/implementation/security/src/security_impl.cpp deleted file mode 100644 index 377e310..0000000 --- a/implementation/security/src/security_impl.cpp +++ /dev/null @@ -1,1196 +0,0 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include - -#ifdef _WIN32 - #define WIN32_LEAN_AND_MEAN - #define NOMINMAX - #include - #include -#endif - -#include - -#include -#include "../include/security_impl.hpp" -#include "../../configuration/include/configuration_element.hpp" -#ifdef ANDROID -#include "../../configuration/include/internal_android.hpp" -#else -#include "../../configuration/include/internal.hpp" -#endif // ANDROID - -namespace vsomeip_v3 { - -template -void read_data(const std::string &_in, T_ &_out) { - std::stringstream its_converter; - - if (_in.size() > 2 - && _in[0] == '0' - && (_in[1] == 'x' || _in[1] == 'X')) - its_converter << std::hex << _in; - else - its_converter << std::dec << _in; - - its_converter >> _out; -} - -security_impl::security_impl() - : policy_enabled_(false), - check_credentials_(false), - check_routing_credentials_(false), - allow_remote_clients_(true), - check_whitelist_(false), - is_configured_(false) { -} - -void -security_impl::load(const configuration_element &_element) { - load_policies(_element); - load_security_update_whitelist(_element); - load_routing_credentials(_element); - - if (policy_enabled_ && check_credentials_) - VSOMEIP_INFO << "Security configuration is active."; - - if (policy_enabled_ && !check_credentials_) - VSOMEIP_INFO << "Security configuration is active but in audit mode (allow all)"; -} - -bool -security_impl::is_enabled() const { - return policy_enabled_; -} - -bool -security_impl::is_audit() const { - return check_credentials_; -} - -bool -security_impl::check_credentials(client_t _client, - uid_t _uid, gid_t _gid) { - - if (!policy_enabled_) { - return true; - } - - std::vector > its_policies; - bool has_id(false); - { - std::lock_guard its_lock(any_client_policies_mutex_); - its_policies = any_client_policies_; - } - - for (const auto &p : its_policies) { - std::lock_guard its_policy_lock(p->mutex_); - - bool has_uid, has_gid(false); - - const auto found_uid = p->credentials_.find(_uid); - has_uid = (found_uid != p->credentials_.end()); - if (has_uid) { - const auto found_gid = found_uid->second.find(_gid); - has_gid = (found_gid != found_uid->second.end()); - } - - has_id = (has_uid && has_gid); - - if ((has_id && p->allow_who_) || (!has_id && !p->allow_who_)) { - if (!store_client_to_uid_gid_mapping(_client,_uid, _gid)) { - std::string security_mode_text = "!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client - << " with UID/GID=" << std::dec << _uid << "/" << _gid - << " : Check credentials failed as existing credentials would be overwritten" - << security_mode_text; - return !check_credentials_; - } - store_uid_gid_to_client_mapping(_uid, _gid, _client); - return true; - } - } - - std::string security_mode_text = " ~> Skip!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client - << " with UID/GID=" << std::dec << _uid << "/" << _gid - << " : Check credentials failed" << security_mode_text; - - return !check_credentials_; -} - -bool -security_impl::is_client_allowed(uint32_t _uid, uint32_t _gid, client_t _client, - service_t _service, instance_t _instance, method_t _method, - bool _is_request_service) const { - - if (!policy_enabled_) { - return true; - } - - uint32_t its_uid(ANY_UID), its_gid(ANY_GID); - std::vector > its_policies; - { - std::lock_guard its_lock(any_client_policies_mutex_); - its_policies = any_client_policies_; - } - - if (_uid != ANY_UID && _gid != ANY_GID) { - its_uid = _uid; - its_gid = _gid; - } else { - std::string security_mode_text = " ~> Skip!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - VSOMEIP_INFO << "vSomeIP Security: uid/gid " << std::dec << _uid << "/" << _gid - << " for client 0x" << std::hex << _client << " is not valid" - << ". Therefore it isn't allowed to communicate to service/instance " - << _service << "/" << _instance - << security_mode_text; - - return !check_credentials_; - } - - for (const auto &p : its_policies) { - std::lock_guard its_policy_lock(p->mutex_); - - bool has_uid, has_gid(false); - bool is_matching(false); - - const auto found_uid = p->credentials_.find(_uid); - has_uid = (found_uid != p->credentials_.end()); - if (has_uid) { - const auto found_gid = found_uid->second.find(_gid); - has_gid = (found_gid != found_uid->second.end()); - } - - const auto found_service = p->requests_.find(_service); - if (found_service != p->requests_.end()) { - const auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - if (!_is_request_service) { - const auto found_method = found_instance->second.find(_method); - is_matching = (found_method != found_instance->second.end()); - } else { - // handle VSOMEIP_REQUEST_SERVICE - is_matching = true; - } - } - } - - if ((has_uid && has_gid && p->allow_who_) || ((!has_uid || !has_gid) && !p->allow_who_)) { - if (p->allow_what_) { - // allow policy - if (is_matching) { - return (true); - } - } else { - // deny policy - // allow client if the service / instance / !ANY_METHOD was not found - if ((!is_matching && (_method != ANY_METHOD)) - // allow client if the service / instance / ANY_METHOD was not found - // and it is a "deny nothing" policy - || (!is_matching && (_method == ANY_METHOD) && p->requests_.empty())) { - return (true); - } - } - } - } - - std::string security_mode_text = " ~> Skip!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - - VSOMEIP_INFO << "vSomeIP Security: Client 0x" << std::hex << _client - << " with UID/GID=" << std::dec << its_uid << "/" << its_gid - << " : Isn't allowed to communicate with service/instance/(method / event) " << std::hex - << _service << "/" << _instance << "/" << _method - << security_mode_text; - - return (!check_credentials_); -} - -bool -security_impl::is_offer_allowed(uint32_t _uid, uint32_t _gid, client_t _client, service_t _service, - instance_t _instance) const { - if (!policy_enabled_) { - return true; - } - - uint32_t its_uid(ANY_UID), its_gid(ANY_GID); - std::vector > its_policies; - { - std::lock_guard its_lock(any_client_policies_mutex_); - its_policies = any_client_policies_; - } - - if (_uid != ANY_UID - && _gid != ANY_GID) { - its_uid = _uid; - its_gid = _gid; - } else { - std::string security_mode_text = " ~> Skip offer!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - VSOMEIP_INFO << "vSomeIP Security: uid/gid " << std::dec << _uid << "/" << _gid - << " for client 0x" << std::hex << _client << " is not valid" - << ". Therefore it isn't allowed to offer service/instance " - << _service << "/" << _instance - << security_mode_text; - - return !check_credentials_; - } - - for (const auto &p : its_policies) { - std::lock_guard its_policy_lock(p->mutex_); - bool has_uid, has_gid(false), has_offer(false); - - const auto found_uid = p->credentials_.find(_uid); - has_uid = (found_uid != p->credentials_.end()); - if (has_uid) { - const auto found_gid = found_uid->second.find(_gid); - has_gid = (found_gid != found_uid->second.end()); - } - - const auto found_service = p->offers_.find(_service); - if (found_service != p->offers_.end()) { - const auto found_instance = found_service->second.find(_instance); - has_offer = (found_instance != found_service->second.end()); - } - - if ((has_uid && has_gid && p->allow_who_) - || ((!has_uid || !has_gid) && !p->allow_who_)) { - if (p->allow_what_ == has_offer) { - return (true); - } - } - } - - std::string security_mode_text = " ~> Skip offer!"; - if (!check_credentials_) { - security_mode_text = " but will be allowed due to audit mode is active!"; - } - - VSOMEIP_INFO << "vSomeIP Security: Client 0x" - << std::hex << _client - << " with UID/GID=" - << std::dec << its_uid << "/" << its_gid - << " isn't allowed to offer service/instance " - << std::hex << _service << "/" << _instance - << security_mode_text; - - return (!check_credentials_); -} - -bool -security_impl::store_client_to_uid_gid_mapping( - client_t _client, uint32_t _uid, uint32_t _gid) { - { - // store the client -> (uid, gid) mapping - std::lock_guard its_lock(ids_mutex_); - auto found_client = ids_.find(_client); - if (found_client != ids_.end()) { - if (found_client->second != std::make_pair(_uid, _gid)) { - VSOMEIP_WARNING << "vSomeIP Security: Client 0x" - << std::hex << _client << " with UID/GID=" - << std::dec << _uid << "/" << _gid << " : Overwriting existing credentials UID/GID=" - << std::dec << std::get<0>(found_client->second) << "/" - << std::get<1>(found_client->second); - found_client->second = std::make_pair(_uid, _gid); - return true; - } - } else { - ids_[_client] = std::make_pair(_uid, _gid); - } - return true; - } -} - -bool -security_impl::get_client_to_uid_gid_mapping(client_t _client, std::pair &_uid_gid) { - { - // get the UID / GID of the client - std::lock_guard its_lock(ids_mutex_); - if (ids_.find(_client) != ids_.end()) { - _uid_gid = ids_[_client]; - return true; - } - return false; - } -} - -bool -security_impl::remove_client_to_uid_gid_mapping(client_t _client) { - std::pair its_uid_gid; - bool client_removed(false); - bool uid_gid_removed(false); - { - std::lock_guard its_lock(ids_mutex_); - auto found_client = ids_.find(_client); - if (found_client != ids_.end()) { - its_uid_gid = found_client->second; - ids_.erase(found_client); - client_removed = true; - } - } - { - std::lock_guard its_lock(uid_to_clients_mutex_); - if (client_removed) { - auto found_uid_gid = uid_to_clients_.find(its_uid_gid); - if (found_uid_gid != uid_to_clients_.end()) { - auto its_client = found_uid_gid->second.find(_client); - if (its_client != found_uid_gid->second.end()) { - found_uid_gid->second.erase(its_client); - if (found_uid_gid->second.empty()) { - uid_to_clients_.erase(found_uid_gid); - } - uid_gid_removed = true; - } - } - } else { - for (auto its_uid_gid = uid_to_clients_.begin(); - its_uid_gid != uid_to_clients_.end(); ++its_uid_gid) { - auto its_client = its_uid_gid->second.find(_client); - if (its_client != its_uid_gid->second.end()) { - its_uid_gid->second.erase(its_client); - if (its_uid_gid->second.empty()) { - uid_to_clients_.erase(its_uid_gid); - } - uid_gid_removed = true; - break; - } - } - } - } - return (client_removed && uid_gid_removed); -} - -void -security_impl::store_uid_gid_to_client_mapping(uint32_t _uid, uint32_t _gid, - client_t _client) { - { - // store the uid gid to clients mapping - std::lock_guard its_lock(uid_to_clients_mutex_); - std::set mapped_clients; - if (uid_to_clients_.find(std::make_pair(_uid, _gid)) != uid_to_clients_.end()) { - mapped_clients = uid_to_clients_[std::make_pair(_uid, _gid)]; - mapped_clients.insert(_client); - uid_to_clients_[std::make_pair(_uid, _gid)] = mapped_clients; - } else { - mapped_clients.insert(_client); - uid_to_clients_[std::make_pair(_uid, _gid)] = mapped_clients; - } - } -} - -bool -security_impl::get_uid_gid_to_client_mapping(std::pair _uid_gid, - std::set &_clients) { - { - // get the clients corresponding to uid, gid - std::lock_guard its_lock(uid_to_clients_mutex_); - if (uid_to_clients_.find(_uid_gid) != uid_to_clients_.end()) { - _clients = uid_to_clients_[_uid_gid]; - return true; - } - return false; - } -} - -bool -security_impl::remove_security_policy(uint32_t _uid, uint32_t _gid) { - std::lock_guard its_lock(any_client_policies_mutex_); - bool was_removed(false); - if (!any_client_policies_.empty()) { - std::vector>::iterator p_it = any_client_policies_.begin(); - while (p_it != any_client_policies_.end()) { - bool is_matching(false); - { - std::lock_guard its_policy_lock((*p_it)->mutex_); - bool has_uid(false), has_gid(false); - const auto found_uid = (*p_it)->credentials_.find(_uid); - has_uid = (found_uid != (*p_it)->credentials_.end()); - if (has_uid) { - const auto found_gid = found_uid->second.find(_gid); - has_gid = (found_gid != found_uid->second.end()); - } - - // only remove "credentials allow" policies to prevent removal of - // blacklist configured in file - if (has_uid && has_gid && (*p_it)->allow_who_) { - is_matching = true; - } - } - if (is_matching) { - was_removed = true; - p_it = any_client_policies_.erase(p_it); - } else { - ++p_it; - } - } - } - return (was_removed); -} - -void -security_impl::update_security_policy(uint32_t _uid, uint32_t _gid, - const std::shared_ptr &_policy) { - - std::lock_guard its_lock(any_client_policies_mutex_); - std::shared_ptr its_matching_policy; - for (auto p : any_client_policies_) { - if (p->credentials_.size() == 1) { - const auto its_uids = *(p->credentials_.begin()); - if (its_uids.first.lower() == _uid - && its_uids.first.upper() == _uid) { - if (its_uids.second.size() == 1) { - const auto its_gids = *(its_uids.second.begin()); - if (its_gids.lower() == _gid - && its_gids.upper() == _gid) { - if (p->allow_who_ == _policy->allow_who_) { - its_matching_policy = p; - break; - } - } - } - } - } - } - - if (its_matching_policy) { - for (const auto &r : _policy->requests_) { - service_t its_lower, its_upper; - get_bounds(r.first, its_lower, its_upper); - for (auto s = its_lower; s <= its_upper; s++) { - boost::icl::discrete_interval its_service(s, s, - boost::icl::interval_bounds::closed()); - its_matching_policy->requests_ += std::make_pair(its_service, r.second); - } - } - for (const auto &o : _policy->offers_) { - service_t its_lower, its_upper; - get_bounds(o.first, its_lower, its_upper); - for (auto s = its_lower; s <= its_upper; s++) { - boost::icl::discrete_interval its_service(s, s, - boost::icl::interval_bounds::closed()); - its_matching_policy->offers_ += std::make_pair(its_service, o.second); - } - } - } else { - any_client_policies_.push_back(_policy); - } -} - -void -security_impl::add_security_credentials(uint32_t _uid, uint32_t _gid, - const std::shared_ptr &_policy, client_t _client) { - - bool was_found(false); - std::lock_guard its_lock(any_client_policies_mutex_); - for (const auto &p : any_client_policies_) { - bool has_uid(false), has_gid(false); - - std::lock_guard its_policy_lock(p->mutex_); - const auto found_uid = p->credentials_.find(_uid); - has_uid = (found_uid != p->credentials_.end()); - if (has_uid) { - const auto found_gid = found_uid->second.find(_gid); - has_gid = (found_gid != found_uid->second.end()); - } - - if (has_uid && has_gid && p->allow_who_) { - was_found = true; - break; - } - } - - // Do not add the new (credentials-only-policy) if a allow - // credentials policy with same credentials was found - if (!was_found) { - any_client_policies_.push_back(_policy); - VSOMEIP_INFO << __func__ << " Added security credentials at client: 0x" - << std::hex << _client << std::dec << " with UID: " << _uid << " GID: " << _gid; - } -} - -bool -security_impl::is_remote_client_allowed() const { - if (!check_credentials_) { - return true; - } - return allow_remote_clients_; -} - -bool -security_impl::is_policy_update_allowed(uint32_t _uid, std::shared_ptr &_policy) const { - - bool is_uid_allowed(false); - { - std::lock_guard its_lock(uid_whitelist_mutex_); - const auto found_uid = uid_whitelist_.find(_uid); - is_uid_allowed = (found_uid != uid_whitelist_.end()); - } - - if (is_uid_allowed) { - std::lock_guard its_lock(service_interface_whitelist_mutex_); - std::lock_guard its_policy_lock(_policy->mutex_); - for (auto its_request : _policy->requests_) { - bool has_service(false); - - service_t its_service(0); - for (its_service = its_request.first.lower(); - its_service <= its_request.first.upper(); - its_service++) { - - const auto found_service = service_interface_whitelist_.find(its_service); - has_service = (found_service != service_interface_whitelist_.end()); - if (!has_service) - break; - } - - if (!has_service) { - if (!check_whitelist_) { - VSOMEIP_INFO << "vSomeIP Security: Policy update requesting service ID: " - << std::hex << its_service - << " is not allowed, but will be allowed due to whitelist audit mode is active!"; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Policy update requesting service ID: " - << std::hex << its_service - << " is not allowed! -> ignore update"; - } - return (!check_whitelist_); - } - } - return (true); - } else { - if (!check_whitelist_) { - VSOMEIP_INFO << "vSomeIP Security: Policy update for UID: " << std::dec << _uid - << " is not allowed, but will be allowed due to whitelist audit mode is active!"; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Policy update for UID: " << std::dec << _uid - << " is not allowed! -> ignore update"; - } - return (!check_whitelist_); - } -} - -bool -security_impl::is_policy_removal_allowed(uint32_t _uid) const { - std::lock_guard its_lock(uid_whitelist_mutex_); - for (auto its_uid_range : uid_whitelist_) { - if (its_uid_range.lower() <= _uid && _uid <= its_uid_range.upper()) { - return (true); - } - } - - if (!check_whitelist_) { - VSOMEIP_INFO << "vSomeIP Security: Policy removal for UID: " - << std::dec << _uid - << " is not allowed, but will be allowed due to whitelist audit mode is active!"; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Policy removal for UID: " - << std::dec << _uid - << " is not allowed! -> ignore removal"; - } - return (!check_whitelist_); -} - -bool -security_impl::check_routing_credentials(client_t _client, - uint32_t _uid, uint32_t _gid) const { - - std::lock_guard its_lock(routing_credentials_mutex_); - if (routing_credentials_.first == _uid - && routing_credentials_.second == _gid) { - - return (true); - } - - std::string security_mode_text = "!"; - if (!check_routing_credentials_) { - - security_mode_text = " but will be allowed due to audit mode is active!"; - } - - VSOMEIP_INFO << "vSomeIP Security: Client 0x" - << std::hex << _client << " and UID/GID=" - << std::dec << _uid << "/" << _gid - << " : Check routing credentials failed as " - << "configured routing manager credentials " - << "do not match with routing manager credentials" - << security_mode_text; - - return (!check_routing_credentials_); -} - -bool -security_impl::parse_policy(const byte_t* &_buffer, uint32_t &_buffer_size, - uint32_t &_uid, uint32_t &_gid, const std::shared_ptr &_policy) const { - - bool is_valid = _policy->deserialize(_buffer, _buffer_size); - if (is_valid) - is_valid = _policy->get_uid_gid(_uid, _gid); - return is_valid; -} - -/////////////////////////////////////////////////////////////////////////////// -// Configuration -/////////////////////////////////////////////////////////////////////////////// -void -security_impl::load_policies(const configuration_element &_element) { -#ifdef _WIN32 - return; -#endif - try { - auto optional = _element.tree_.get_child_optional("security"); - if (!optional) { - return; - } - policy_enabled_ = true; - auto found_policy = _element.tree_.get_child("security"); - for (auto its_security = found_policy.begin(); - its_security != found_policy.end(); ++its_security) { - if (its_security->first == "check_credentials") { - if (its_security->second.data() == "true") { - check_credentials_ = true; - } else { - check_credentials_ = false; - } - } else if (its_security->first == "allow_remote_clients") { - if (its_security->second.data() == "true") { - allow_remote_clients_ = true; - } else { - allow_remote_clients_ = false; - } - } else if (its_security->first == "policies") { - for (auto its_policy = its_security->second.begin(); - its_policy != its_security->second.end(); ++its_policy) { - load_policy(its_policy->second); - } - } - } - } catch (...) { - } -} - -void -security_impl::load_policy(const boost::property_tree::ptree &_tree) { - - std::shared_ptr policy(std::make_shared()); - bool allow_deny_set(false); - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - if (i->first == "credentials") { - boost::icl::interval_set its_uid_interval_set; - boost::icl::interval_set its_gid_interval_set; - boost::icl::discrete_interval its_uid_interval; - boost::icl::discrete_interval its_gid_interval; - - bool has_uid(false), has_gid(false); - bool has_uid_range(false), has_gid_range(false); - for (auto n = i->second.begin(); - n != i->second.end(); ++n) { - std::string its_key(n->first); - std::string its_value(n->second.data()); - if (its_key == "uid") { - if(n->second.data().empty()) { - load_interval_set(n->second, its_uid_interval_set); - has_uid_range = true; - } else { - if (its_value != "any") { - uint32_t its_uid; - read_data(its_value, its_uid); - its_uid_interval = boost::icl::construct< - boost::icl::discrete_interval >( - its_uid, its_uid, - boost::icl::interval_bounds::closed()); - } else { - its_uid_interval = boost::icl::construct< - boost::icl::discrete_interval >( - std::numeric_limits::min(), - std::numeric_limits::max(), - boost::icl::interval_bounds::closed()); - } - has_uid = true; - } - } else if (its_key == "gid") { - if(n->second.data().empty()) { - load_interval_set(n->second, its_gid_interval_set); - has_gid_range = true; - } else { - if (its_value != "any") { - uint32_t its_gid; - read_data(its_value, its_gid); - its_gid_interval = boost::icl::construct< - boost::icl::discrete_interval >( - its_gid, its_gid, - boost::icl::interval_bounds::closed()); - } else { - its_gid_interval = boost::icl::construct< - boost::icl::discrete_interval >( - std::numeric_limits::min(), - std::numeric_limits::max(), - boost::icl::interval_bounds::closed()); - } - has_gid = true; - } - } else if (its_key == "allow" || its_key == "deny") { - policy->allow_who_ = (its_key == "allow"); - load_credential(n->second, policy->credentials_); - } - } - - if (has_uid && has_gid) { - its_gid_interval_set.insert(its_gid_interval); - - policy->credentials_ += std::make_pair(its_uid_interval, its_gid_interval_set); - policy->allow_who_ = true; - } - if (has_uid_range && has_gid_range) { - for (const auto& u : its_uid_interval_set) - policy->credentials_ += std::make_pair(u, its_gid_interval_set); - policy->allow_who_ = true; - } - } else if (i->first == "allow") { - if (allow_deny_set) { - VSOMEIP_WARNING << "vSomeIP Security: Security configuration: \"allow\" tag overrides " - << "already set \"deny\" tag. " - << "Either \"deny\" or \"allow\" is allowed."; - } - allow_deny_set = true; - policy->allow_what_ = true; - load_policy_body(policy, i); - } else if (i->first == "deny") { - if (allow_deny_set) { - VSOMEIP_WARNING << "vSomeIP Security: Security configuration: \"deny\" tag overrides " - << "already set \"allow\" tag. " - << "Either \"deny\" or \"allow\" is allowed."; - } - allow_deny_set = true; - policy->allow_what_ = false; - load_policy_body(policy, i); - } - } - std::lock_guard its_lock(any_client_policies_mutex_); - any_client_policies_.push_back(policy); -} - -void -security_impl::load_policy_body(std::shared_ptr &_policy, - const boost::property_tree::ptree::const_iterator &_tree) { - - for (auto l = _tree->second.begin(); l != _tree->second.end(); ++l) { - if (l->first == "requests") { - for (auto n = l->second.begin(); n != l->second.end(); ++n) { - service_t its_service = 0x0; - instance_t its_instance = 0x0; - boost::icl::interval_map > its_instance_method_intervals; - for (auto k = n->second.begin(); k != n->second.end(); ++k) { - if (k->first == "service") { - read_data(k->second.data(), its_service); - } else if (k->first == "instance") { // legacy definition for instances - boost::icl::interval_set its_instance_interval_set; - boost::icl::interval_set its_method_interval_set; - boost::icl::discrete_interval all_instances(0x01, 0xFFFF, - boost::icl::interval_bounds::closed()); - boost::icl::discrete_interval all_methods(0x01, 0xFFFF, - boost::icl::interval_bounds::closed()); - - std::string its_value(k->second.data()); - if (its_value != "any") { - read_data(its_value, its_instance); - if (its_instance != 0x0) { - its_instance_interval_set.insert(its_instance); - its_method_interval_set.insert(all_methods); - } - } else { - its_instance_interval_set.insert(all_instances); - its_method_interval_set.insert(all_methods); - } - for (const auto& i : its_instance_interval_set) { - its_instance_method_intervals - += std::make_pair(i, its_method_interval_set); - } - } else if (k->first == "instances") { // new instances definition - for (auto p = k->second.begin(); p != k->second.end(); ++p) { - boost::icl::interval_set its_instance_interval_set; - boost::icl::interval_set its_method_interval_set; - boost::icl::discrete_interval all_methods(0x01, 0xFFFF, - boost::icl::interval_bounds::closed()); - for (auto m = p->second.begin(); m != p->second.end(); ++m) { - if (m->first == "ids") { - load_interval_set(m->second, its_instance_interval_set); - } else if (m->first == "methods") { - load_interval_set(m->second, its_method_interval_set); - } - } - if (its_method_interval_set.empty()) - its_method_interval_set.insert(all_methods); - for (const auto& i : its_instance_interval_set) { - its_instance_method_intervals - += std::make_pair(i, its_method_interval_set); - } - } - - if (its_instance_method_intervals.empty()) { - boost::icl::interval_set its_legacy_instance_interval_set; - boost::icl::interval_set its_legacy_method_interval_set; - boost::icl::discrete_interval all_methods(0x01, 0xFFFF, - boost::icl::interval_bounds::closed()); - its_legacy_method_interval_set.insert(all_methods); - - // try to only load instance ranges with any method to be allowed - load_interval_set(k->second, its_legacy_instance_interval_set); - for (const auto& i : its_legacy_instance_interval_set) { - its_instance_method_intervals - += std::make_pair(i, its_legacy_method_interval_set); - } - } - } - } - if (its_service != 0x0 && !its_instance_method_intervals.empty()) { - _policy->requests_ += std::make_pair( - boost::icl::discrete_interval( - its_service, its_service, - boost::icl::interval_bounds::closed()), - its_instance_method_intervals); - } - } - } else if (l->first == "offers") { - for (auto n = l->second.begin(); n != l->second.end(); ++n) { - service_t its_service(0x0); - instance_t its_instance(0x0); - boost::icl::interval_set its_instance_interval_set; - for (auto k = n->second.begin(); k != n->second.end(); ++k) { - if (k->first == "service") { - read_data(k->second.data(), its_service); - } else if (k->first == "instance") { // legacy definition for instances - std::string its_value(k->second.data()); - if (its_value != "any") { - read_data(its_value, its_instance); - if (its_instance != 0x0) { - its_instance_interval_set.insert(its_instance); - } - } else { - its_instance_interval_set.insert( - boost::icl::discrete_interval( - 0x0001, 0xFFFF)); - } - } else if (k->first == "instances") { // new instances definition - load_interval_set(k->second, its_instance_interval_set); - } - } - if (its_service != 0x0 && !its_instance_interval_set.empty()) { - _policy->offers_ - += std::make_pair( - boost::icl::discrete_interval( - its_service, its_service, - boost::icl::interval_bounds::closed()), - its_instance_interval_set); - } - } - } - } -} - - -void -security_impl::load_credential( - const boost::property_tree::ptree &_tree, - boost::icl::interval_map > &_credentials) { - - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - boost::icl::interval_set its_uid_interval_set; - boost::icl::interval_set its_gid_interval_set; - - for (auto j = i->second.begin(); j != i->second.end(); ++j) { - std::string its_key(j->first); - if (its_key == "uid") { - load_interval_set(j->second, its_uid_interval_set); - } else if (its_key == "gid") { - load_interval_set(j->second, its_gid_interval_set); - } else { - VSOMEIP_WARNING << "vSomeIP Security: Security configuration: " - << "Malformed credential (contains illegal key \"" - << its_key << "\")"; - } - } - - for (const auto& its_uid_interval : its_uid_interval_set) { - _credentials - += std::make_pair(its_uid_interval, its_gid_interval_set); - } - } -} - -bool -security_impl::load_routing_credentials(const configuration_element &_element) { - try { - auto its_routing_cred = _element.tree_.get_child("routing-credentials"); - if (is_configured_) { - VSOMEIP_WARNING << "vSomeIP Security: Multiple definitions of routing-credentials." - << " Ignoring definition from " << _element.name_; - } else { - for (auto i = its_routing_cred.begin(); - i != its_routing_cred.end(); - ++i) { - std::string its_key(i->first); - std::string its_value(i->second.data()); - if (its_key == "uid") { - uint32_t its_uid(0); - read_data(its_value, its_uid); - std::lock_guard its_lock(routing_credentials_mutex_); - std::get<0>(routing_credentials_) = its_uid; - } else if (its_key == "gid") { - uint32_t its_gid(0); - read_data(its_value, its_gid); - std::lock_guard its_lock(routing_credentials_mutex_); - std::get<1>(routing_credentials_) = its_gid; - } - } - check_routing_credentials_ = true; - is_configured_ = true; - } - } catch (...) { - return false; - } - return true; -} - - -void -security_impl::load_security_update_whitelist(const configuration_element &_element) { -#ifdef _WIN32 - return; -#endif - try { - auto optional = _element.tree_.get_child_optional("security-update-whitelist"); - if (!optional) { - return; - } - auto found_whitelist = _element.tree_.get_child("security-update-whitelist"); - for (auto its_whitelist = found_whitelist.begin(); - its_whitelist != found_whitelist.end(); ++its_whitelist) { - - if (its_whitelist->first == "uids") { - { - std::lock_guard its_lock(uid_whitelist_mutex_); - load_interval_set(its_whitelist->second, uid_whitelist_); - } - } else if (its_whitelist->first == "services") { - { - std::lock_guard its_lock(service_interface_whitelist_mutex_); - load_interval_set(its_whitelist->second, service_interface_whitelist_); - } - } else if (its_whitelist->first == "check-whitelist") { - if (its_whitelist->second.data() == "true") { - check_whitelist_ = true; - } else { - check_whitelist_ = false; - } - } - } - } catch (...) { - } -} - -template -void security_impl::load_interval_set( - const boost::property_tree::ptree &_tree, - boost::icl::interval_set &_intervals, bool _exclude_margins) { - - boost::icl::interval_set its_intervals; - T_ its_min = std::numeric_limits::min(); - T_ its_max = std::numeric_limits::max(); - - if (_exclude_margins) { - its_min++; - its_max--; - } - - const std::string its_key(_tree.data()); - if (its_key == "any") { - its_intervals.insert(boost::icl::discrete_interval::closed( - its_min, its_max)); - } else { - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - auto its_data = i->second; - if (!its_data.data().empty()) { - T_ its_id; - read_data(its_data.data(), its_id); - if (its_id >= its_min && its_id <= its_max) - its_intervals.insert(its_id); - } else { - T_ its_first, its_last; - bool has_first(false), has_last(false); - for (auto j = its_data.begin(); j != its_data.end(); ++j) { - std::string its_key(j->first); - std::string its_value(j->second.data()); - if (its_key == "first") { - if (its_value == "min") { - its_first = its_min; - } else { - read_data(its_value, its_first); - } - has_first = true; - } else if (its_key == "last") { - if (its_value == "max") { - its_last = its_max; - } else { - read_data(its_value, its_last); - } - has_last = true; - } else { - VSOMEIP_WARNING << "vSomeIP Security: Security configuration: " - << " Malformed range. Contains illegal key (" - << its_key << ")"; - } - } - if (has_first && has_last && its_first <= its_last) { - its_intervals.insert( - boost::icl::discrete_interval::closed(its_first, its_last)); - } - } - } - } - - _intervals = its_intervals; -} - -void -security_impl::get_requester_policies(const std::shared_ptr _policy, - std::set > &_requesters) const { - - std::vector > its_policies; - { - std::lock_guard its_lock(any_client_policies_mutex_); - its_policies = any_client_policies_; - } - - std::lock_guard its_lock(_policy->mutex_); - for (const auto &o : _policy->offers_) { - for (const auto &p : its_policies) { - if (p == _policy) - continue; - - std::lock_guard its_lock(p->mutex_); - - auto its_policy = std::make_shared(); - its_policy->credentials_ = p->credentials_; - - for (const auto &r : p->requests_) { - // o represents an offer by a service interval and its instances - // (a set of intervals) - // r represents a request by a service interval and its instances - // and methods (instance intervals mapped to interval sets of methods) - // - // Thus, r matches o if their service identifiers as well as their - // instances overlap. If r and o match, a new policy must be - // created that contains the overlapping services/instances mapping - // of r and o together with the methods from r - service_t its_o_lower, its_o_upper, its_r_lower, its_r_upper; - get_bounds(o.first, its_o_lower, its_o_upper); - get_bounds(r.first, its_r_lower, its_r_upper); - - if (its_o_lower <= its_r_upper && its_r_lower <= its_o_upper) { - auto its_service_min = std::max(its_o_lower, its_r_lower); - auto its_service_max = std::min(its_r_upper, its_o_upper); - - for (const auto &i : o.second) { - for (const auto &j : r.second) { - for (const auto& k : j.second) { - instance_t its_i_lower, its_i_upper, its_k_lower, its_k_upper; - get_bounds(i, its_i_lower, its_i_upper); - get_bounds(k, its_k_lower, its_k_upper); - - if (its_i_lower <= its_k_upper && its_k_lower <= its_i_upper) { - auto its_instance_min = std::max(its_i_lower, its_k_lower); - auto its_instance_max = std::min(its_i_upper, its_k_upper); - - boost::icl::interval_map > its_instances_methods; - its_instances_methods += std::make_pair( - boost::icl::interval::closed( - its_instance_min, its_instance_max), - j.second); - - its_policy->requests_ += std::make_pair( - boost::icl::interval::closed( - its_service_min, its_service_max), - its_instances_methods); - } - } - } - } - } - } - - if (!its_policy->requests_.empty()) { - _requesters.insert(its_policy); - its_policy->print(); - } - } - } -} - -void -security_impl::get_clients(uid_t _uid, gid_t _gid, - std::unordered_set &_clients) const { - - std::lock_guard its_lock(ids_mutex_); - for (const auto &i : ids_) { - if (i.second.first == _uid && i.second.second == _gid) - _clients.insert(i.first); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// Manage the security object -//////////////////////////////////////////////////////////////////////////////// -static std::shared_ptr *the_security_ptr__(nullptr); -static std::mutex the_security_mutex__; - -std::shared_ptr -security_impl::get() { -#ifndef _WIN32 - std::lock_guard its_lock(the_security_mutex__); -#endif - if(the_security_ptr__ == nullptr) { - the_security_ptr__ = new std::shared_ptr(); - } - if (the_security_ptr__ != nullptr) { - if (!(*the_security_ptr__)) { - *the_security_ptr__ = std::make_shared(); - } - return (*the_security_ptr__); - } - return (nullptr); -} - -#ifndef _WIN32 -static void security_teardown(void) __attribute__((destructor)); -static void security_teardown(void) -{ - if (the_security_ptr__ != nullptr) { - std::lock_guard its_lock(the_security_mutex__); - the_security_ptr__->reset(); - delete the_security_ptr__; - the_security_ptr__ = nullptr; - } -} -#endif - -} // namespace vsomeip_v3 diff --git a/implementation/service_discovery/include/configuration_option_impl.hpp b/implementation/service_discovery/include/configuration_option_impl.hpp index 567762d..e1dde72 100644 --- a/implementation/service_discovery/include/configuration_option_impl.hpp +++ b/implementation/service_discovery/include/configuration_option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -25,7 +25,7 @@ public: configuration_option_impl(); virtual ~configuration_option_impl(); - bool operator==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; void add_item(const std::string &_key, const std::string &_value); void remove_item(const std::string &_key); diff --git a/implementation/service_discovery/include/constants.hpp b/implementation/service_discovery/include/constants.hpp index c50fac1..3ebb259 100644 --- a/implementation/service_discovery/include/constants.hpp +++ b/implementation/service_discovery/include/constants.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/defines.hpp b/implementation/service_discovery/include/defines.hpp index b7e840b..b7642f1 100644 --- a/implementation/service_discovery/include/defines.hpp +++ b/implementation/service_discovery/include/defines.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,7 +12,7 @@ #define VSOMEIP_SOMEIP_SD_DATA_SIZE 12 #define VSOMEIP_SOMEIP_SD_ENTRY_LENGTH_SIZE 4 #define VSOMEIP_SOMEIP_SD_ENTRY_SIZE 16 -#define VSOMEIP_SOMEIP_SD_IPV4_OPTION_SIZE 12 +#define VSOMEIP_SOMEIP_SD_IPV3_OPTION_SIZE 12 #define VSOMEIP_SOMEIP_SD_IPV6_OPTION_SIZE 24 #define VSOMEIP_SOMEIP_SD_LOAD_BALANCING_OPTION_SIZE 8 #define VSOMEIP_SOMEIP_SD_PROTECTION_OPTION_SIZE 12 diff --git a/implementation/service_discovery/include/deserializer.hpp b/implementation/service_discovery/include/deserializer.hpp old mode 100755 new mode 100644 index 97ebcd4..866ebda --- a/implementation/service_discovery/include/deserializer.hpp +++ b/implementation/service_discovery/include/deserializer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/entry_impl.hpp b/implementation/service_discovery/include/entry_impl.hpp old mode 100755 new mode 100644 index 39d5416..ed22c8f --- a/implementation/service_discovery/include/entry_impl.hpp +++ b/implementation/service_discovery/include/entry_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/enumeration_types.hpp b/implementation/service_discovery/include/enumeration_types.hpp index 63d0378..0b6c71b 100644 --- a/implementation/service_discovery/include/enumeration_types.hpp +++ b/implementation/service_discovery/include/enumeration_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/eventgroupentry_impl.hpp b/implementation/service_discovery/include/eventgroupentry_impl.hpp old mode 100755 new mode 100644 index 08b25a6..efb9b07 --- a/implementation/service_discovery/include/eventgroupentry_impl.hpp +++ b/implementation/service_discovery/include/eventgroupentry_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/ip_option_impl.hpp b/implementation/service_discovery/include/ip_option_impl.hpp index c83d745..842be84 100644 --- a/implementation/service_discovery/include/ip_option_impl.hpp +++ b/implementation/service_discovery/include/ip_option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,7 +19,7 @@ public: ip_option_impl(); ip_option_impl(const uint16_t _port, const bool _is_reliable); virtual ~ip_option_impl(); - virtual bool operator ==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; uint16_t get_port() const; void set_port(uint16_t _port); diff --git a/implementation/service_discovery/include/ipv4_option_impl.hpp b/implementation/service_discovery/include/ipv4_option_impl.hpp index 15c04b2..7e97078 100644 --- a/implementation/service_discovery/include/ipv4_option_impl.hpp +++ b/implementation/service_discovery/include/ipv4_option_impl.hpp @@ -1,10 +1,10 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. -#ifndef VSOMEIP_V3_SD_IPV4_OPTION_IMPL_HPP_ -#define VSOMEIP_V3_SD_IPV4_OPTION_IMPL_HPP_ +#ifndef VSOMEIP_V3_SD_IPV3_OPTION_IMPL_HPP_ +#define VSOMEIP_V3_SD_IPV3_OPTION_IMPL_HPP_ #include @@ -22,7 +22,7 @@ public: const uint16_t _port, const bool _is_reliable); virtual ~ipv4_option_impl(); - bool operator ==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; const ipv4_address_t & get_address() const; void set_address(const ipv4_address_t &_address); @@ -38,5 +38,5 @@ private: } // namespace sd } // namespace vsomeip_v3 -#endif // VSOMEIP_V3_SD_IPV4_OPTION_IMPL_HPP_ +#endif // VSOMEIP_V3_SD_IPV3_OPTION_IMPL_HPP_ diff --git a/implementation/service_discovery/include/ipv6_option_impl.hpp b/implementation/service_discovery/include/ipv6_option_impl.hpp index d896300..17a613b 100644 --- a/implementation/service_discovery/include/ipv6_option_impl.hpp +++ b/implementation/service_discovery/include/ipv6_option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -23,7 +23,7 @@ public: const uint16_t _port, const bool _is_reliable); virtual ~ipv6_option_impl(); - bool operator ==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; const ipv6_address_t & get_address() const; void set_address(const ipv6_address_t &_address); diff --git a/implementation/service_discovery/include/load_balancing_option_impl.hpp b/implementation/service_discovery/include/load_balancing_option_impl.hpp old mode 100755 new mode 100644 index dafcfc7..15fa917 --- a/implementation/service_discovery/include/load_balancing_option_impl.hpp +++ b/implementation/service_discovery/include/load_balancing_option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -17,7 +17,7 @@ public: load_balancing_option_impl(); virtual ~load_balancing_option_impl(); - bool operator ==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; priority_t get_priority() const; void set_priority(priority_t _priority); diff --git a/implementation/service_discovery/include/message_element_impl.hpp b/implementation/service_discovery/include/message_element_impl.hpp old mode 100755 new mode 100644 index 29b5d86..2ce979b --- a/implementation/service_discovery/include/message_element_impl.hpp +++ b/implementation/service_discovery/include/message_element_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/message_impl.hpp b/implementation/service_discovery/include/message_impl.hpp old mode 100755 new mode 100644 index b9e858d..faeb9d6 --- a/implementation/service_discovery/include/message_impl.hpp +++ b/implementation/service_discovery/include/message_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -36,7 +36,7 @@ class serviceentry_impl; class option_impl; class configuration_option_impl; -class ipv4_option_impl; +class ipv3_option_impl; class ipv6_option_impl; class load_balancing_option_impl; class protection_option_impl; @@ -45,8 +45,8 @@ class selective_option_impl; class message_impl : public vsomeip_v3::message, public vsomeip_v3::message_base_impl { public: - typedef std::vector> entries_t; - typedef std::vector> options_t; + using entries_t = std::vector>; + using options_t = std::vector>; struct forced_initial_events_t { std::shared_ptr target_; vsomeip_v3::service_t service_; @@ -104,6 +104,8 @@ public: uid_t get_uid() const; gid_t get_gid() const; + vsomeip_sec_client_t get_sec_client() const; + std::string get_env() const; private: entry_impl * deserialize_entry(vsomeip_v3::deserializer *_from); diff --git a/implementation/service_discovery/include/option_impl.hpp b/implementation/service_discovery/include/option_impl.hpp index e171c74..3c898b6 100644 --- a/implementation/service_discovery/include/option_impl.hpp +++ b/implementation/service_discovery/include/option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -26,8 +26,7 @@ public: option_impl(); virtual ~option_impl(); - virtual bool operator ==(const option_impl &_other) const; - bool equals(const std::shared_ptr &_other) const; + virtual bool equals(const option_impl &_other) const; uint16_t get_length() const; option_type_e get_type() const; diff --git a/implementation/service_discovery/include/primitive_types.hpp b/implementation/service_discovery/include/primitive_types.hpp index fd093e9..cf152c8 100644 --- a/implementation/service_discovery/include/primitive_types.hpp +++ b/implementation/service_discovery/include/primitive_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,15 +12,15 @@ namespace vsomeip_v3 { namespace sd { // Load balancing -typedef uint16_t priority_t; -typedef uint16_t weight_t; +using priority_t = std::uint16_t; +using weight_t = std::uint16_t; // Protection -typedef uint32_t alive_counter_t; -typedef uint32_t crc_t; +using alive_counter_t = std::uint32_t; +using crc_t = std::uint32_t; // -typedef uint8_t flags_t; +using flags_t = std::uint8_t; } // namespace sd } // namespace vsomeip_v3 diff --git a/implementation/service_discovery/include/protection_option_impl.hpp b/implementation/service_discovery/include/protection_option_impl.hpp old mode 100755 new mode 100644 index 792d7cc..7e34eb5 --- a/implementation/service_discovery/include/protection_option_impl.hpp +++ b/implementation/service_discovery/include/protection_option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -17,7 +17,7 @@ public: protection_option_impl(); virtual ~protection_option_impl(); - bool operator ==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; alive_counter_t get_alive_counter() const; void set_alive_counter(alive_counter_t _counter); diff --git a/implementation/service_discovery/include/remote_subscription_ack.hpp b/implementation/service_discovery/include/remote_subscription_ack.hpp index 1bc8792..7b2b635 100644 --- a/implementation/service_discovery/include/remote_subscription_ack.hpp +++ b/implementation/service_discovery/include/remote_subscription_ack.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/request.hpp b/implementation/service_discovery/include/request.hpp index 0e6e2ec..4d4dba0 100644 --- a/implementation/service_discovery/include/request.hpp +++ b/implementation/service_discovery/include/request.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/runtime.hpp b/implementation/service_discovery/include/runtime.hpp index 0772de4..fe9f27b 100644 --- a/implementation/service_discovery/include/runtime.hpp +++ b/implementation/service_discovery/include/runtime.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/runtime_impl.hpp b/implementation/service_discovery/include/runtime_impl.hpp index 0010de6..1b5bfa4 100644 --- a/implementation/service_discovery/include/runtime_impl.hpp +++ b/implementation/service_discovery/include/runtime_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/selective_option_impl.hpp b/implementation/service_discovery/include/selective_option_impl.hpp index 863408f..b4d7bcb 100644 --- a/implementation/service_discovery/include/selective_option_impl.hpp +++ b/implementation/service_discovery/include/selective_option_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2018-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -25,7 +25,7 @@ public: selective_option_impl(); virtual ~selective_option_impl(); - bool operator==(const option_impl &_other) const; + bool equals(const option_impl &_other) const; std::set get_clients() const; void set_clients(const std::set &_clients); diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp index 77b4258..cab33a8 100644 --- a/implementation/service_discovery/include/service_discovery.hpp +++ b/implementation/service_discovery/include/service_discovery.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,7 +6,6 @@ #ifndef VSOMEIP_V3_SD_SERVICE_DISCOVERY_HPP_ #define VSOMEIP_V3_SD_SERVICE_DISCOVERY_HPP_ -#include #include #include @@ -28,7 +27,7 @@ public: virtual ~service_discovery() { } - virtual boost::asio::io_service & get_io() = 0; + virtual boost::asio::io_context &get_io() = 0; virtual void init() = 0; virtual void start() = 0; @@ -51,14 +50,15 @@ public: virtual void on_message(const byte_t *_data, length_t _length, const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination) = 0; + bool _is_multicast) = 0; virtual void on_endpoint_connected( service_t _service, instance_t _instance, const std::shared_ptr &_endpoint) = 0; virtual void offer_service(const std::shared_ptr &_info) = 0; - virtual void stop_offer_service(const std::shared_ptr &_info) = 0; + virtual bool stop_offer_service(const std::shared_ptr &_info, bool _send) = 0; + virtual bool send_collected_stop_offers(const std::vector> &_infos) = 0; virtual void set_diagnosis_mode(const bool _activate) = 0; @@ -68,9 +68,9 @@ public: const std::shared_ptr &_subscription) = 0; virtual void register_sd_acceptance_handler( - sd_acceptance_handler_t _handler) = 0; + const sd_acceptance_handler_t &_handler) = 0; virtual void register_reboot_notification_handler( - reboot_notification_handler_t _handler) = 0; + const reboot_notification_handler_t &_handler) = 0; }; } // namespace sd diff --git a/implementation/service_discovery/include/service_discovery_host.hpp b/implementation/service_discovery/include/service_discovery_host.hpp index 0f992d7..09b5301 100644 --- a/implementation/service_discovery/include/service_discovery_host.hpp +++ b/implementation/service_discovery/include/service_discovery_host.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,7 +11,12 @@ #include #include -#include +#if VSOMEIP_BOOST_VERSION < 106600 +# include +# define io_context io_service +#else +# include +#endif #include "../../routing/include/function_types.hpp" #include "../../routing/include/types.hpp" @@ -31,7 +36,7 @@ public: virtual ~service_discovery_host() { } - virtual boost::asio::io_service & get_io() = 0; + virtual boost::asio::io_context &get_io() = 0; virtual std::shared_ptr create_service_discovery_endpoint( const std::string &_address, uint16_t _port, bool _reliable) = 0; @@ -40,7 +45,8 @@ public: virtual std::shared_ptr find_eventgroup(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const = 0; - virtual bool send(client_t _client, std::shared_ptr _message) = 0; + virtual bool send(client_t _client, std::shared_ptr _message, + bool _force) = 0; virtual bool send_via_sd(const std::shared_ptr &_target, const byte_t *_data, uint32_t _size, uint16_t _sd_port) = 0; @@ -86,7 +92,7 @@ public: virtual void on_subscribe_nack(client_t _client, service_t _service, instance_t _instance, eventgroup_t _eventgroup, - event_t _event, remote_subscription_id_t _subscription_id, bool _simulated) = 0; + event_t _event, remote_subscription_id_t _subscription_id) = 0; virtual std::chrono::steady_clock::time_point expire_subscriptions(bool _force) = 0; diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp index c4e3835..b2270e1 100644 --- a/implementation/service_discovery/include/service_discovery_impl.hpp +++ b/implementation/service_discovery/include/service_discovery_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -44,11 +44,7 @@ class serviceentry_impl; class service_discovery_host; class subscription; -typedef std::map - > - > requests_t; +using requests_t = std::map>>; struct entry_data_t { std::shared_ptr entry_; @@ -63,7 +59,7 @@ public: const std::shared_ptr& _configuration); virtual ~service_discovery_impl(); - boost::asio::io_service & get_io(); + boost::asio::io_context &get_io(); void init(); void start(); @@ -86,14 +82,15 @@ public: void on_message(const byte_t *_data, length_t _length, const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination); + bool _is_multicast); void on_endpoint_connected( service_t _service, instance_t _instance, const std::shared_ptr &_endpoint); void offer_service(const std::shared_ptr &_info); - void stop_offer_service(const std::shared_ptr &_info); + bool stop_offer_service(const std::shared_ptr &_info, bool _send); + bool send_collected_stop_offers(const std::vector> &_infos); void set_diagnosis_mode(const bool _activate); @@ -103,16 +100,19 @@ public: void update_remote_subscription( const std::shared_ptr &_subscription); - void register_sd_acceptance_handler(sd_acceptance_handler_t _handler); + void register_sd_acceptance_handler(const sd_acceptance_handler_t &_handler); void register_reboot_notification_handler( - reboot_notification_handler_t _handler); + const reboot_notification_handler_t &_handler); private: std::pair get_session(const boost::asio::ip::address &_address); void increment_session(const boost::asio::ip::address &_address); bool is_reboot(const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination, - bool _reboot_flag, session_t _session); + bool _is_multicast, bool _reboot_flag, session_t _session); + + bool check_session_id_sequence(const boost::asio::ip::address &_sender, + const bool _is_multicast, const session_t &_session, + session_t &_missing_session); void insert_find_entries(std::vector > &_messages, const requests_t &_requests); @@ -120,12 +120,6 @@ private: const services_t &_services, bool _ignore_phase); void insert_offer_service(std::vector > &_messages, const std::shared_ptr &_info); - enum remote_offer_type_e : std::uint8_t { - RELIABLE_UNRELIABLE, - RELIABLE, - UNRELIABLE, - UNKNOWN = 0xff - }; entry_data_t create_eventgroup_entry( service_t _service, instance_t _instance, eventgroup_t _eventgroup, @@ -138,7 +132,7 @@ private: const std::shared_ptr &_target, const std::set &_clients); - typedef std::set> expired_ports_t; + using expired_ports_t = std::set>; struct sd_acceptance_state_t { explicit sd_acceptance_state_t(expired_ports_t& _expired_ports) : expired_ports_(_expired_ports), @@ -178,7 +172,7 @@ private: const std::vector > &_options, std::shared_ptr &_acknowledgement, const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination, + bool _is_multicast, bool _is_stop_subscribe_subscribe, bool _force_initial_events, const sd_acceptance_state_t& _sd_ac_state); void handle_eventgroup_subscription(service_t _service, @@ -215,7 +209,7 @@ private: instance_t _instance, const std::shared_ptr& its_endpoint); - void start_ttl_timer(); + void start_ttl_timer(int _shift = 0); void stop_ttl_timer(); void check_ttl(const boost::system::error_code &_error); @@ -310,13 +304,13 @@ private: void on_last_msg_received_timer_expired(const boost::system::error_code &_error); void stop_last_msg_received_timer(); - remote_offer_type_e get_remote_offer_type( + reliability_type_e get_remote_offer_type( service_t _service, instance_t _instance) const; - remote_offer_type_e get_remote_offer_type( + reliability_type_e get_remote_offer_type( const std::shared_ptr &_subscription) const; bool update_remote_offer_type(service_t _service, instance_t _instance, - remote_offer_type_e _offer_type, + reliability_type_e _offer_type, const boost::asio::ip::address &_reliable_address, std::uint16_t _reliable_port, const boost::asio::ip::address &_unreliable_address, @@ -362,7 +356,7 @@ private: const std::shared_ptr& _subscription); private: - boost::asio::io_service &io_; + boost::asio::io_context &io_; service_discovery_host *host_; std::shared_ptr configuration_; @@ -463,7 +457,7 @@ private: std::chrono::milliseconds last_msg_received_timer_timeout_; mutable std::mutex remote_offer_types_mutex_; - std::map, remote_offer_type_e> remote_offer_types_; + std::map, reliability_type_e> remote_offer_types_; std::map, std::set>>> remote_offers_by_ip_; @@ -479,4 +473,3 @@ private: } // namespace vsomeip_v3 #endif // VSOMEIP_V3_SD_SERVICE_DISCOVERY_IMPL_ - diff --git a/implementation/service_discovery/include/serviceentry_impl.hpp b/implementation/service_discovery/include/serviceentry_impl.hpp index f7b2b92..8e1cf70 100644 --- a/implementation/service_discovery/include/serviceentry_impl.hpp +++ b/implementation/service_discovery/include/serviceentry_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/include/subscription.hpp b/implementation/service_discovery/include/subscription.hpp index adbd66c..8c1e074 100644 --- a/implementation/service_discovery/include/subscription.hpp +++ b/implementation/service_discovery/include/subscription.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/configuration_option_impl.cpp b/implementation/service_discovery/src/configuration_option_impl.cpp old mode 100755 new mode 100644 index 9666e5e..c1f6917 --- a/implementation/service_discovery/src/configuration_option_impl.cpp +++ b/implementation/service_discovery/src/configuration_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -21,8 +21,8 @@ configuration_option_impl::~configuration_option_impl() { } bool -configuration_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(option_impl::operator ==(_other)); +configuration_option_impl::equals(const option_impl &_other) const { + bool is_equal(option_impl::equals(_other)); if (is_equal) { const configuration_option_impl &its_other @@ -123,8 +123,6 @@ bool configuration_option_impl::deserialize(vsomeip_v3::deserializer *_from) { is_successful = false; } } - } else { - break; } } while (is_successful && _from->get_remaining() > 0); diff --git a/implementation/service_discovery/src/deserializer.cpp b/implementation/service_discovery/src/deserializer.cpp index 88ce3be..046a523 100644 --- a/implementation/service_discovery/src/deserializer.cpp +++ b/implementation/service_discovery/src/deserializer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/entry_impl.cpp b/implementation/service_discovery/src/entry_impl.cpp old mode 100755 new mode 100644 index 1fa1c89..3873d0a --- a/implementation/service_discovery/src/entry_impl.cpp +++ b/implementation/service_discovery/src/entry_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/eventgroupentry_impl.cpp b/implementation/service_discovery/src/eventgroupentry_impl.cpp old mode 100755 new mode 100644 index 28fdcec..f23fd74 --- a/implementation/service_discovery/src/eventgroupentry_impl.cpp +++ b/implementation/service_discovery/src/eventgroupentry_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -118,8 +118,8 @@ bool eventgroupentry_impl::matches(const eventgroupentry_impl& _other, std::vector> its_options_current; std::vector> its_options_other; const std::size_t its_options_size = _options.size(); - for (const auto& option_run : {0,1}) { - for (const auto& option_index : options_[option_run]) { + for (const auto option_run : {0,1}) { + for (const auto option_index : options_[option_run]) { if (its_options_size > option_index) { switch (_options[option_index]->get_type()) { case option_type_e::IP4_ENDPOINT: @@ -137,7 +137,7 @@ bool eventgroupentry_impl::matches(const eventgroupentry_impl& _other, } } } - for (const auto& option_index : _other.options_[option_run]) { + for (const auto option_index : _other.options_[option_run]) { if (its_options_size > option_index) { switch (_options[option_index]->get_type()) { case option_type_e::IP4_ENDPOINT: @@ -165,7 +165,7 @@ bool eventgroupentry_impl::matches(const eventgroupentry_impl& _other, for (const auto& c : its_options_current) { bool found(false); for (const auto& o : its_options_other) { - if (*c == *o) { + if (c->equals(*o)) { switch (c->get_type()) { case option_type_e::IP4_ENDPOINT: if (static_cast(c.get())->get_address() @@ -212,8 +212,8 @@ std::shared_ptr eventgroupentry_impl::get_target( std::shared_ptr eventgroupentry_impl::get_selective_option() const { - for (const auto& i : {0, 1}) { - for (const auto& j : options_[i]) { + for (const auto i : {0, 1}) { + for (const auto j : options_[i]) { auto its_option = std::dynamic_pointer_cast< selective_option_impl>(owner_->get_option(j)); if (its_option) diff --git a/implementation/service_discovery/src/ip_option_impl.cpp b/implementation/service_discovery/src/ip_option_impl.cpp index 0f83511..197013f 100644 --- a/implementation/service_discovery/src/ip_option_impl.cpp +++ b/implementation/service_discovery/src/ip_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -29,8 +29,8 @@ ip_option_impl::~ip_option_impl() { } bool -ip_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(option_impl::operator ==(_other)); +ip_option_impl::equals(const option_impl &_other) const { + bool is_equal(option_impl::equals(_other)); if (is_equal) { const ip_option_impl &its_other diff --git a/implementation/service_discovery/src/ipv4_option_impl.cpp b/implementation/service_discovery/src/ipv4_option_impl.cpp index f3389e8..f2eef95 100644 --- a/implementation/service_discovery/src/ipv4_option_impl.cpp +++ b/implementation/service_discovery/src/ipv4_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -31,8 +31,8 @@ ipv4_option_impl::~ipv4_option_impl() { } bool -ipv4_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(ip_option_impl::operator ==(_other)); +ipv4_option_impl::equals(const option_impl &_other) const { + bool is_equal(ip_option_impl::equals(_other)); if (is_equal) { const ipv4_option_impl &its_other = dynamic_cast(_other); diff --git a/implementation/service_discovery/src/ipv6_option_impl.cpp b/implementation/service_discovery/src/ipv6_option_impl.cpp old mode 100755 new mode 100644 index 1baba0f..e2bc30e --- a/implementation/service_discovery/src/ipv6_option_impl.cpp +++ b/implementation/service_discovery/src/ipv6_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -31,8 +31,8 @@ ipv6_option_impl::~ipv6_option_impl() { } bool -ipv6_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(ip_option_impl::operator ==(_other)); +ipv6_option_impl::equals(const option_impl &_other) const { + bool is_equal(ip_option_impl::equals(_other)); if (is_equal) { const ipv6_option_impl &its_other diff --git a/implementation/service_discovery/src/load_balancing_option_impl.cpp b/implementation/service_discovery/src/load_balancing_option_impl.cpp old mode 100755 new mode 100644 index a26509e..1e30788 --- a/implementation/service_discovery/src/load_balancing_option_impl.cpp +++ b/implementation/service_discovery/src/load_balancing_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -21,8 +21,8 @@ load_balancing_option_impl::~load_balancing_option_impl() { } bool -load_balancing_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(option_impl::operator ==(_other)); +load_balancing_option_impl::equals(const option_impl &_other) const { + bool is_equal(option_impl::equals(_other)); if (is_equal) { const load_balancing_option_impl &its_other diff --git a/implementation/service_discovery/src/message_element_impl.cpp b/implementation/service_discovery/src/message_element_impl.cpp old mode 100755 new mode 100644 index 281a0a7..afdb507 --- a/implementation/service_discovery/src/message_element_impl.cpp +++ b/implementation/service_discovery/src/message_element_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/message_impl.cpp b/implementation/service_discovery/src/message_impl.cpp old mode 100755 new mode 100644 index a203ce7..c00da19 --- a/implementation/service_discovery/src/message_impl.cpp +++ b/implementation/service_discovery/src/message_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -178,7 +178,7 @@ const message_impl::options_t & message_impl::get_options() const { std::shared_ptr message_impl::find_option(const std::shared_ptr &_option) const { for (auto its_option : options_) { - if (its_option->equals(_option)) + if (its_option->equals(*_option)) return its_option; } return nullptr; @@ -419,13 +419,24 @@ length_t message_impl::get_someip_length() const { } uid_t message_impl::get_uid() const { - return ANY_UID; + return (ANY_UID); } gid_t message_impl::get_gid() const { - return ANY_GID; + return (ANY_GID); } +vsomeip_sec_client_t message_impl::get_sec_client() const { + static vsomeip_sec_client_t its_dummy_sec_client{ + VSOMEIP_CLIENT_UDS, {vsomeip_sec_uds_client_credentials_t{ANY_UID, ANY_GID}} + }; + + return (its_dummy_sec_client); +} + +std::string message_impl::get_env() const { + return (""); +} } // namespace sd } // namespace vsomeip_v3 diff --git a/implementation/service_discovery/src/option_impl.cpp b/implementation/service_discovery/src/option_impl.cpp old mode 100755 new mode 100644 index eb92c1a..c055ff4 --- a/implementation/service_discovery/src/option_impl.cpp +++ b/implementation/service_discovery/src/option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,13 +19,9 @@ option_impl::option_impl() : option_impl::~option_impl() { } -bool option_impl::operator ==(const option_impl &_other) const { - return (type_ == _other.type_ && length_ == _other.length_); -} - bool -option_impl::equals(const std::shared_ptr &_other) const { - return (this->operator ==(*(_other.get()))); +option_impl::equals(const option_impl &_other) const { + return (type_ == _other.get_type() && length_ == _other.get_length()); } uint16_t option_impl::get_length() const { diff --git a/implementation/service_discovery/src/protection_option_impl.cpp b/implementation/service_discovery/src/protection_option_impl.cpp old mode 100755 new mode 100644 index 801ca88..6d79860 --- a/implementation/service_discovery/src/protection_option_impl.cpp +++ b/implementation/service_discovery/src/protection_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -21,8 +21,8 @@ protection_option_impl::~protection_option_impl() { } bool -protection_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(option_impl::operator ==(_other)); +protection_option_impl::equals(const option_impl &_other) const { + bool is_equal(option_impl::equals(_other)); if (is_equal) { const protection_option_impl &its_other diff --git a/implementation/service_discovery/src/remote_subscription_ack.cpp b/implementation/service_discovery/src/remote_subscription_ack.cpp index 03270c9..45fa057 100644 --- a/implementation/service_discovery/src/remote_subscription_ack.cpp +++ b/implementation/service_discovery/src/remote_subscription_ack.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/request.cpp b/implementation/service_discovery/src/request.cpp index 819b1a5..ee6b10b 100644 --- a/implementation/service_discovery/src/request.cpp +++ b/implementation/service_discovery/src/request.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/runtime_impl.cpp b/implementation/service_discovery/src/runtime_impl.cpp index 75ce986..f0fa456 100644 --- a/implementation/service_discovery/src/runtime_impl.cpp +++ b/implementation/service_discovery/src/runtime_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/selective_option_impl.cpp b/implementation/service_discovery/src/selective_option_impl.cpp old mode 100755 new mode 100644 index 17063d9..7fe62c9 --- a/implementation/service_discovery/src/selective_option_impl.cpp +++ b/implementation/service_discovery/src/selective_option_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2018-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -21,8 +21,8 @@ selective_option_impl::~selective_option_impl() { } bool -selective_option_impl::operator ==(const option_impl &_other) const { - bool is_equal(option_impl::operator ==(_other)); +selective_option_impl::equals(const option_impl &_other) const { + bool is_equal(option_impl::equals(_other)); if (is_equal) { const selective_option_impl &its_other = dynamic_cast(_other); diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp index 74e509b..19effad 100644 --- a/implementation/service_discovery/src/service_discovery_impl.cpp +++ b/implementation/service_discovery/src/service_discovery_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -81,8 +81,7 @@ service_discovery_impl::service_discovery_impl( service_discovery_impl::~service_discovery_impl() { } -boost::asio::io_service & -service_discovery_impl::get_io() { +boost::asio::io_context &service_discovery_impl::get_io() { return io_; } @@ -164,11 +163,13 @@ service_discovery_impl::start() { i.second->set_sent_counter(0); } } + + // rejoin multicast group if (endpoint_ && !reliable_) { - auto its_endpoint = std::dynamic_pointer_cast< - udp_server_endpoint_impl>(endpoint_); - if (its_endpoint) - its_endpoint->join(sd_multicast_); + auto its_server_endpoint + = std::dynamic_pointer_cast(endpoint_); + if (its_server_endpoint) + its_server_endpoint->join(sd_multicast_); } } is_suspended_ = false; @@ -524,6 +525,7 @@ service_discovery_impl::unsubscribe_all( serialize_and_send(its_messages, its_address); } + void service_discovery_impl::unsubscribe_all_on_suspend() { @@ -616,12 +618,11 @@ service_discovery_impl::increment_session( bool service_discovery_impl::is_reboot( const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination, + bool _is_multicast, bool _reboot_flag, session_t _session) { bool result(false); auto its_received = sessions_received_.find(_sender); - bool is_multicast = _destination.is_multicast(); // Initialize both sessions with 0. Thus, the session identifier // for the session not being received from the network is stored @@ -632,7 +633,7 @@ service_discovery_impl::is_reboot( // received from the network will never trigger the reboot detection. bool its_multicast_reboot_flag(true), its_unicast_reboot_flag(true); - if (is_multicast) { + if (_is_multicast) { its_multicast_session = _session; its_multicast_reboot_flag = _reboot_flag; } else { @@ -648,14 +649,14 @@ service_discovery_impl::is_reboot( // Reboot detection: Either the flag has changed from false to true, // or the session identifier overrun while the flag is true. if (_reboot_flag - && ((is_multicast && !std::get<2>(its_received->second)) - || (!is_multicast && !std::get<3>(its_received->second)))) { + && ((_is_multicast && !std::get<2>(its_received->second)) + || (!_is_multicast && !std::get<3>(its_received->second)))) { result = true; } else { session_t its_old_session; bool its_old_reboot_flag; - if (is_multicast) { + if (_is_multicast) { its_old_session = std::get<0>(its_received->second); its_old_reboot_flag = std::get<2>(its_received->second); } else { @@ -671,7 +672,7 @@ service_discovery_impl::is_reboot( if (result == false) { // no reboot -> update session/flag - if (is_multicast) { + if (_is_multicast) { std::get<0>(its_received->second) = its_multicast_session; std::get<2>(its_received->second) = its_multicast_reboot_flag; } else { @@ -687,6 +688,27 @@ service_discovery_impl::is_reboot( return result; } +bool +service_discovery_impl::check_session_id_sequence(const boost::asio::ip::address &_sender, + const bool _is_multicast, const session_t &_session, + session_t &_missing_session) { + + using address_pair_t = std::pair; + static std::map session_peer; + address_pair_t peer_to_peer(_sender, _is_multicast); + std::map::iterator it = session_peer.find(peer_to_peer); + if (it != session_peer.end()) { + if ((_session > it->second) && (_session != (it->second+1))) { + _missing_session = static_cast(it->second+1); + session_peer[peer_to_peer] = _session; + return false; + } + } + + session_peer[peer_to_peer] = _session; + return true; +} + void service_discovery_impl::insert_find_entries( std::vector > &_messages, @@ -839,7 +861,7 @@ service_discovery_impl::create_eventgroup_entry( its_entry->set_ttl(_subscription->get_ttl()); its_data.entry_ = its_entry; - for (const auto& its_client : _subscription->get_clients()) { + for (const auto its_client : _subscription->get_clients()) { if (_subscription->get_state(its_client) == subscription_state_e::ST_RESUBSCRIBING_NOT_ACKNOWLEDGED) { its_other = std::make_shared(); @@ -890,7 +912,7 @@ service_discovery_impl::create_eventgroup_entry( its_data.entry_ = its_entry; } - for (const auto& its_client : _subscription->get_clients()) { + for (const auto its_client : _subscription->get_clients()) { if (_subscription->get_state(its_client) == subscription_state_e::ST_RESUBSCRIBING_NOT_ACKNOWLEDGED) { if (!its_other) { @@ -1043,7 +1065,7 @@ service_discovery_impl::send(bool _is_announcing) { std::lock_guard its_lock(offer_mutex_); services_t its_offers = host_->get_offered_services(); - insert_offer_entries(its_messages, its_offers, true); + insert_offer_entries(its_messages, its_offers, false); // Serialize and send return send(its_messages); @@ -1057,7 +1079,7 @@ void service_discovery_impl::on_message( const byte_t *_data, length_t _length, const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination) { + bool _is_multicast) { #if 0 std::stringstream msg; msg << "sdi::on_message: "; @@ -1075,8 +1097,8 @@ service_discovery_impl::on_message( if (!check_source_address(_sender)) { return; } - const bool received_via_mcast = (_destination == sd_multicast_address_); - if (received_via_mcast) { + + if (_is_multicast) { static bool must_start_last_msg_received_timer(true); boost::system::error_code ec; @@ -1102,7 +1124,7 @@ service_discovery_impl::on_message( return; } // Expire all subscriptions / services in case of reboot - if (is_reboot(_sender, _destination, + if (is_reboot(_sender, _is_multicast, its_message->get_reboot_flag(), its_message->get_session())) { VSOMEIP_INFO << "Reboot detected: IP=" << _sender.to_string(); remove_remote_offer_type_by_ip(_sender); @@ -1121,6 +1143,23 @@ service_discovery_impl::on_message( } } + session_t start_missing_sessions; + if (!check_session_id_sequence(_sender, _is_multicast, its_message->get_session(), start_missing_sessions)) { + std::stringstream log; + log << "SD messages lost from " << _sender.to_string() << " to "; + if (_is_multicast) { + log << sd_multicast_address_.to_string(); + } else { + log << unicast_.to_string(); + } + log << " - session_id[" << start_missing_sessions; + if (its_message->get_session() - start_missing_sessions != 1) { + log << ":" << its_message->get_session() -1; + } + log << "]"; + VSOMEIP_WARNING << log.str(); + } + std::vector > its_options = its_message->get_options(); @@ -1171,7 +1210,7 @@ service_discovery_impl::on_message( bool its_unicast_flag = its_message->get_unicast_flag(); process_serviceentry(its_service_entry, its_options, its_unicast_flag, its_resubscribes, - received_via_mcast, accept_state); + _is_multicast, accept_state); } else { std::shared_ptr its_eventgroup_entry = std::dynamic_pointer_cast(*iter); @@ -1190,7 +1229,7 @@ service_discovery_impl::on_message( is_stop_subscribe_subscribe = check_stop_subscribe_subscribe(iter, its_end, its_options); process_eventgroupentry(its_eventgroup_entry, its_options, - its_acknowledgement, _sender, _destination, + its_acknowledgement, _sender, _is_multicast, is_stop_subscribe_subscribe, force_initial_events, accept_state); } @@ -1330,7 +1369,7 @@ service_discovery_impl::process_serviceentry( VSOMEIP_ERROR << __func__ << ": Unsupported service entry type"; } } else if (its_type != entry_type_e::FIND_SERVICE - && (!_sd_ac_state.sd_acceptance_required_ || _sd_ac_state.accept_entries_)) { + && (_sd_ac_state.sd_acceptance_required_ || _sd_ac_state.accept_entries_)) { // stop sending find service in repetition phase update_request(its_service, its_instance); @@ -1378,19 +1417,10 @@ service_discovery_impl::process_offerservice_serviceentry( // stop sending find service in repetition phase update_request(_service, _instance); - remote_offer_type_e offer_type(remote_offer_type_e::UNKNOWN); - if (_reliable_port != ILLEGAL_PORT - && _unreliable_port != ILLEGAL_PORT - && !_reliable_address.is_unspecified() - && !_unreliable_address.is_unspecified()) { - offer_type = remote_offer_type_e::RELIABLE_UNRELIABLE; - } else if (_unreliable_port != ILLEGAL_PORT - && !_unreliable_address.is_unspecified()) { - offer_type = remote_offer_type_e::UNRELIABLE; - } else if (_reliable_port != ILLEGAL_PORT - && !_reliable_address.is_unspecified()) { - offer_type = remote_offer_type_e::RELIABLE; - } else { + const reliability_type_e offer_type = configuration_->get_reliability_type( + _reliable_address, _reliable_port, _unreliable_address,_unreliable_port); + + if (offer_type == reliability_type_e::RT_UNKNOWN) { VSOMEIP_WARNING << __func__ << ": Unknown remote offer type [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "]"; @@ -1419,7 +1449,7 @@ service_discovery_impl::process_offerservice_serviceentry( // return if the registered sd_acceptance handler returned false // and for the provided port sd_acceptance is necessary switch (offer_type) { - case remote_offer_type_e::UNRELIABLE: + case reliability_type_e::RT_UNRELIABLE: if (!_sd_ac_state.accept_entries_ && configuration_->is_protected_port( _unreliable_address, _unreliable_port, false)) { @@ -1428,7 +1458,7 @@ service_discovery_impl::process_offerservice_serviceentry( return; } break; - case remote_offer_type_e::RELIABLE: + case reliability_type_e::RT_RELIABLE: if (!_sd_ac_state.accept_entries_ && configuration_->is_protected_port( _reliable_address, _reliable_port, true)) { @@ -1437,7 +1467,7 @@ service_discovery_impl::process_offerservice_serviceentry( return; } break; - case remote_offer_type_e::RELIABLE_UNRELIABLE: + case reliability_type_e::RT_BOTH: if (!_sd_ac_state.accept_entries_ && (configuration_->is_protected_port( _unreliable_address, _unreliable_port, false) @@ -1450,7 +1480,7 @@ service_discovery_impl::process_offerservice_serviceentry( return; } break; - case remote_offer_type_e::UNKNOWN: + case reliability_type_e::RT_UNKNOWN: default: break; } @@ -1470,36 +1500,21 @@ service_discovery_impl::process_offerservice_serviceentry( _service, _instance, eg); if (its_info) { if (its_info->is_reliability_auto_mode()) { - reliability_type_e its_reliability(reliability_type_e::RT_UNKNOWN); - switch (offer_type) { - case remote_offer_type_e::RELIABLE: - its_reliability = reliability_type_e::RT_RELIABLE; - break; - case remote_offer_type_e::UNRELIABLE: - its_reliability = reliability_type_e::RT_UNRELIABLE; - break; - case remote_offer_type_e::RELIABLE_UNRELIABLE: - its_reliability = reliability_type_e::RT_BOTH; - break; - default: - ; - } - if (its_reliability != reliability_type_e::RT_UNKNOWN - && its_reliability != its_info->get_reliability()) { + if (offer_type != reliability_type_e::RT_UNKNOWN + && offer_type != its_info->get_reliability()) { VSOMEIP_WARNING << "sd::" << __func__ << ": eventgroup reliability type changed [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "." << std::hex << std::setw(4) << std::setfill('0') << eg << "]" << " using reliability type: " - << std::hex << std::setw(4) << std::setfill('0') << (uint16_t) its_reliability; - its_info->set_reliability(its_reliability); + << std::hex << std::setw(4) << std::setfill('0') << (uint16_t) offer_type; + its_info->set_reliability(offer_type); } } } } } - // No need to resubscribe for unicast offers if (_received_via_mcast) { std::lock_guard its_lock(subscribed_mutex_); @@ -1534,7 +1549,7 @@ service_discovery_impl::process_offerservice_serviceentry( if (its_data.entry_) { add_entry_data(_resubscribes, its_data); } - for (const auto& its_client : its_subscription->get_clients()) { + for (const auto its_client : its_subscription->get_clients()) { its_subscription->set_state(its_client, subscription_state_e::ST_NOT_ACKNOWLEDGED); } @@ -1770,7 +1785,7 @@ service_discovery_impl::process_eventgroupentry( const std::vector > &_options, std::shared_ptr &_acknowledgement, const boost::asio::ip::address &_sender, - const boost::asio::ip::address &_destination, + bool _is_multicast, bool _is_stop_subscribe_subscribe, bool _force_initial_events, const sd_acceptance_state_t& _sd_ac_state) { @@ -1835,8 +1850,8 @@ service_discovery_impl::process_eventgroupentry( return; } - if(its_type == entry_type_e::SUBSCRIBE_EVENTGROUP) { - if (_destination.is_multicast() ) { + if (its_type == entry_type_e::SUBSCRIBE_EVENTGROUP) { + if (_is_multicast) { boost::system::error_code ec; VSOMEIP_ERROR << __func__ << ": Received a SubscribeEventGroup entry on multicast address " @@ -1874,7 +1889,7 @@ service_discovery_impl::process_eventgroupentry( } if (_options.size() // cast is needed in order to get unsigned type since int will be promoted - // by the + operator on 16 bit or higher machines. + // by the + operator on 16 bit or higher machines. < static_cast>::size_type>( (_entry->get_num_options(1)) + (_entry->get_num_options(2)))) { boost::system::error_code ec; @@ -1916,10 +1931,7 @@ service_discovery_impl::process_eventgroupentry( std::shared_ptr < option_impl > its_option; try { its_option = _options.at(its_index); - } catch(const std::out_of_range& e) { -#ifdef _WIN32 - e; // silence MSVC warning C4101 -#endif + } catch(const std::out_of_range&) { boost::system::error_code ec; VSOMEIP_ERROR << __func__ << ": Fewer options in SD message than " @@ -2335,7 +2347,6 @@ service_discovery_impl::handle_eventgroup_subscription( // check if TCP connection is established by client if (_ttl > 0 && !is_tcp_connected(_service, _instance, its_reliable)) { insert_subscription_ack(_acknowledgement, _info, 0, nullptr, _clients); - boost::system::error_code ec; // TODO: Add sender and session id VSOMEIP_ERROR << "TCP connection to target1: [" << its_reliable->get_address().to_string() @@ -2365,7 +2376,6 @@ service_discovery_impl::handle_eventgroup_subscription( // check if TCP connection is established by client if (_ttl > 0 && !is_tcp_connected(_service, _instance, its_reliable)) { insert_subscription_ack(_acknowledgement, _info, 0, nullptr, _clients); - boost::system::error_code ec; // TODO: Add sender and session id VSOMEIP_ERROR << "TCP connection to target2 : [" << its_reliable->get_address().to_string() @@ -2456,10 +2466,10 @@ service_discovery_impl::handle_eventgroup_subscription_nack( auto found_eventgroup = found_instance->second.find(_eventgroup); if (found_eventgroup != found_instance->second.end()) { auto its_subscription = found_eventgroup->second; - for (const auto& its_client : _clients) { + for (const auto its_client : _clients) { host_->on_subscribe_nack(its_client, _service, _instance, _eventgroup, ANY_EVENT, - PENDING_SUBSCRIPTION_ID, false); // TODO: This is a dummy call... + PENDING_SUBSCRIPTION_ID); // TODO: This is a dummy call... } @@ -2491,7 +2501,7 @@ service_discovery_impl::handle_eventgroup_subscription_ack( if (found_instance != found_service->second.end()) { auto found_eventgroup = found_instance->second.find(_eventgroup); if (found_eventgroup != found_instance->second.end()) { - for (const auto& its_client : _clients) { + for (const auto its_client : _clients) { if (found_eventgroup->second->get_state(its_client) == subscription_state_e::ST_NOT_ACKNOWLEDGED) { found_eventgroup->second->set_state(its_client, @@ -2521,7 +2531,7 @@ bool service_discovery_impl::is_tcp_connected(service_t _service, auto its_reliable_server_endpoint = std::dynamic_pointer_cast< tcp_server_endpoint_impl>(its_info->get_endpoint(true)); if (its_reliable_server_endpoint - && its_reliable_server_endpoint->is_established(its_endpoint)) { + && its_reliable_server_endpoint->is_established_to(its_endpoint)) { is_connected = true; } } @@ -2538,7 +2548,7 @@ service_discovery_impl::send( std::pair its_session = get_session(unicast_); m->set_session(its_session.first); m->set_reboot_flag(its_session.second); - if (host_->send(VSOMEIP_SD_CLIENT, m)) { + if (host_->send(VSOMEIP_SD_CLIENT, m, true)) { increment_session(unicast_); } } else { @@ -2583,10 +2593,21 @@ service_discovery_impl::serialize_and_send( } void -service_discovery_impl::start_ttl_timer() { +service_discovery_impl::start_ttl_timer(int _shift) { + std::lock_guard its_lock(ttl_timer_mutex_); + + std::chrono::milliseconds its_timeout(ttl_timer_runtime_); + if (_shift > 0) { + if (its_timeout.count() > _shift) + its_timeout -= std::chrono::milliseconds(_shift); + + if (its_timeout.count() > VSOMEIP_MINIMUM_CHECK_TTL_TIMEOUT) + its_timeout = std::chrono::milliseconds(VSOMEIP_MINIMUM_CHECK_TTL_TIMEOUT); + } + boost::system::error_code ec; - ttl_timer_.expires_from_now(std::chrono::milliseconds(ttl_timer_runtime_), ec); + ttl_timer_.expires_from_now(its_timeout, ec); ttl_timer_.async_wait( std::bind(&service_discovery_impl::check_ttl, shared_from_this(), std::placeholders::_1)); @@ -2601,12 +2622,20 @@ service_discovery_impl::stop_ttl_timer() { void service_discovery_impl::check_ttl(const boost::system::error_code &_error) { + + static int its_counter(0); // count the times we were not able to call + // update_routing_info if (!_error) { { - std::lock_guard its_lock(check_ttl_mutex_); - host_->update_routing_info(ttl_timer_runtime_); + std::unique_lock its_lock(check_ttl_mutex_, std::try_to_lock); + if (its_lock.owns_lock()) { + its_counter = 0; + host_->update_routing_info(ttl_timer_runtime_); + } else { + its_counter++; + } } - start_ttl_timer(); + start_ttl_timer(its_counter * VSOMEIP_MINIMUM_CHECK_TTL_TIMEOUT); } } @@ -2684,11 +2713,11 @@ service_discovery_impl::check_ipv4_address( //Check unallowed ipv4 address bool is_valid = true; - const boost::asio::ip::address_v4::bytes_type its_unicast_address = + static const boost::asio::ip::address_v4::bytes_type its_unicast_address = unicast_.to_v4().to_bytes(); const boost::asio::ip::address_v4::bytes_type endpoint_address = its_address.to_v4().to_bytes(); - const boost::asio::ip::address_v4::bytes_type its_netmask = + static const boost::asio::ip::address_v4::bytes_type its_netmask = configuration_->get_netmask().to_v4().to_bytes(); //same address as unicast address of DUT not allowed @@ -2750,8 +2779,6 @@ service_discovery_impl::start_offer_debounce_timer(bool _first_start) { this, std::placeholders::_1)); } - - void service_discovery_impl::start_find_debounce_timer(bool _first_start) { std::lock_guard its_lock(find_debounce_timer_mutex_); @@ -2989,7 +3016,6 @@ service_discovery_impl::on_repetition_phase_timer_expired( } } - void service_discovery_impl::on_find_repetition_phase_timer_expired( const boost::system::error_code &_error, @@ -3033,7 +3059,6 @@ service_discovery_impl::on_find_repetition_phase_timer_expired( } } - void service_discovery_impl::move_offers_into_main_phase( const std::shared_ptr &_timer) { @@ -3051,9 +3076,9 @@ service_discovery_impl::move_offers_into_main_phase( } } -void +bool service_discovery_impl::stop_offer_service( - const std::shared_ptr &_info) { + const std::shared_ptr &_info, bool _send) { std::lock_guard its_lock(offer_mutex_); _info->set_ttl(0); const service_t its_service = _info->get_service(); @@ -3106,10 +3131,15 @@ service_discovery_impl::stop_offer_service( } } } - // Sent stop offer - if(_info->is_in_mainphase() || stop_offer_required) { - send_stop_offer(_info); + + if (!_send) { + // stop offer required + return (_info->is_in_mainphase() || stop_offer_required); + } else if(_info->is_in_mainphase() || stop_offer_required) { + // Send stop offer + return send_stop_offer(_info); } + return false; // sent out NACKs for all pending subscriptions // TODO: remote_subscription_not_acknowledge_all(its_service, its_instance); } @@ -3131,11 +3161,30 @@ service_discovery_impl::send_stop_offer(const std::shared_ptr &_inf return false; } +bool +service_discovery_impl::send_collected_stop_offers(const std::vector> &_infos) { + + std::vector > its_messages; + std::shared_ptr its_current_message( + std::make_shared()); + its_messages.push_back(its_current_message); + + // pack multiple stop offers together + for (auto its_info : _infos) { + if (its_info->get_endpoint(false) || its_info->get_endpoint(true)) { + insert_offer_service(its_messages, its_info); + } + } + + // Serialize and send + return send(its_messages); +} + void service_discovery_impl::start_main_phase_timer() { std::lock_guard its_lock(main_phase_timer_mutex_); boost::system::error_code ec; - main_phase_timer_.expires_from_now(cyclic_offer_delay_); + main_phase_timer_.expires_from_now(cyclic_offer_delay_, ec); if (ec) { VSOMEIP_ERROR<< "service_discovery_impl::start_main_phase_timer " "setting expiry time of timer failed: " << ec.message(); @@ -3249,7 +3298,6 @@ service_discovery_impl::update_acknowledgement( } } - void service_discovery_impl::update_subscription_expiration_timer( const std::vector > &_messages) { @@ -3426,10 +3474,12 @@ service_discovery_impl::on_last_msg_received_timer_expired( // Rejoin multicast group if (endpoint_ && !reliable_) { - auto its_endpoint = std::dynamic_pointer_cast< - udp_server_endpoint_impl>(endpoint_); - if (its_endpoint) - its_endpoint->join(sd_multicast_); + auto its_server_endpoint + = std::dynamic_pointer_cast(endpoint_); + if (its_server_endpoint) { + its_server_endpoint->leave(sd_multicast_); + its_server_endpoint->join(sd_multicast_); + } } { boost::system::error_code ec; @@ -3450,7 +3500,7 @@ service_discovery_impl::stop_last_msg_received_timer() { last_msg_received_timer_.cancel(ec); } -service_discovery_impl::remote_offer_type_e +reliability_type_e service_discovery_impl::get_remote_offer_type( service_t _service, instance_t _instance) const { std::lock_guard its_lock(remote_offer_types_mutex_); @@ -3458,10 +3508,10 @@ service_discovery_impl::get_remote_offer_type( if (found_si != remote_offer_types_.end()) { return found_si->second; } - return remote_offer_type_e::UNKNOWN; + return reliability_type_e::RT_UNKNOWN; } -service_discovery_impl::remote_offer_type_e +reliability_type_e service_discovery_impl::get_remote_offer_type( const std::shared_ptr &_subscription) const { bool has_reliable = (_subscription->get_endpoint(true) != nullptr); @@ -3469,18 +3519,18 @@ service_discovery_impl::get_remote_offer_type( return (has_reliable ? (has_unreliable ? - remote_offer_type_e::RELIABLE_UNRELIABLE : - remote_offer_type_e::RELIABLE) : + reliability_type_e::RT_BOTH : + reliability_type_e::RT_RELIABLE) : (has_unreliable ? - remote_offer_type_e::UNRELIABLE : - remote_offer_type_e::UNKNOWN)); + reliability_type_e::RT_UNRELIABLE : + reliability_type_e::RT_UNKNOWN)); } bool service_discovery_impl::update_remote_offer_type( service_t _service, instance_t _instance, - remote_offer_type_e _offer_type, + reliability_type_e _offer_type, const boost::asio::ip::address &_reliable_address, std::uint16_t _reliable_port, const boost::asio::ip::address &_unreliable_address, @@ -3498,26 +3548,26 @@ service_discovery_impl::update_remote_offer_type( remote_offer_types_[its_si_pair] = _offer_type; } switch (_offer_type) { - case remote_offer_type_e::UNRELIABLE: + case reliability_type_e::RT_UNRELIABLE: remote_offers_by_ip_[_unreliable_address][std::make_pair(false, _unreliable_port)].insert(its_si_pair); break; - case remote_offer_type_e::RELIABLE: + case reliability_type_e::RT_RELIABLE: remote_offers_by_ip_[_reliable_address][std::make_pair(true, _reliable_port)].insert(its_si_pair); break; - case remote_offer_type_e::RELIABLE_UNRELIABLE: + case reliability_type_e::RT_BOTH: remote_offers_by_ip_[_unreliable_address][std::make_pair(false, _unreliable_port)].insert(its_si_pair); remote_offers_by_ip_[_unreliable_address][std::make_pair(true, _reliable_port)].insert(its_si_pair); break; - case remote_offer_type_e::UNKNOWN: + case reliability_type_e::RT_UNKNOWN: default: VSOMEIP_WARNING << __func__ << ": unknown offer type [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "]" - << _offer_type; + << static_cast(_offer_type); break; } return ret; @@ -3754,13 +3804,13 @@ service_discovery_impl::add_entry_data_to_remote_subscription_ack_msg( void service_discovery_impl::register_sd_acceptance_handler( - sd_acceptance_handler_t _handler) { + const sd_acceptance_handler_t &_handler) { sd_acceptance_handler_ = _handler; } void service_discovery_impl::register_reboot_notification_handler( - reboot_notification_handler_t _handler) { + const reboot_notification_handler_t &_handler) { reboot_notification_handler_ = _handler; } @@ -3775,19 +3825,7 @@ reliability_type_e service_discovery_impl::get_eventgroup_reliability( && its_info->is_reliability_auto_mode()) { // fallback: determine how service is offered // and update reliability type of eventgroup - switch (get_remote_offer_type(_service, _instance)) { - case remote_offer_type_e::RELIABLE: - its_reliability = reliability_type_e::RT_RELIABLE; - break; - case remote_offer_type_e::UNRELIABLE: - its_reliability = reliability_type_e::RT_UNRELIABLE; - break; - case remote_offer_type_e::RELIABLE_UNRELIABLE: - its_reliability = reliability_type_e::RT_BOTH; - break; - default: - ; - } + its_reliability = get_remote_offer_type(_service, _instance); VSOMEIP_WARNING << "sd::" << __func__ << ": couldn't determine eventgroup reliability type for [" << std::hex << std::setw(4) << std::setfill('0') << _service << "." << std::hex << std::setw(4) << std::setfill('0') << _instance << "." @@ -3814,10 +3852,8 @@ reliability_type_e service_discovery_impl::get_eventgroup_reliability( << std::hex << std::setw(4) << std::setfill('0') << _instance << "." << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]"; } - return its_reliability; } - } // namespace sd } // namespace vsomeip_v3 diff --git a/implementation/service_discovery/src/serviceentry_impl.cpp b/implementation/service_discovery/src/serviceentry_impl.cpp old mode 100755 new mode 100644 index 9ea86b1..f3fc70d --- a/implementation/service_discovery/src/serviceentry_impl.cpp +++ b/implementation/service_discovery/src/serviceentry_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/service_discovery/src/subscription.cpp b/implementation/service_discovery/src/subscription.cpp index 9a95bec..8ceaf1b 100644 --- a/implementation/service_discovery/src/subscription.cpp +++ b/implementation/service_discovery/src/subscription.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -100,7 +100,7 @@ std::set subscription::get_clients() const { std::set its_clients; { std::lock_guard its_lock(clients_mutex_); - for (const auto& its_item : clients_) + for (const auto its_item : clients_) its_clients.insert(its_item.first); } return its_clients; diff --git a/implementation/tracing/include/channel_impl.hpp b/implementation/tracing/include/channel_impl.hpp index cc2e583..a00d8c5 100644 --- a/implementation/tracing/include/channel_impl.hpp +++ b/implementation/tracing/include/channel_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2017-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,12 +12,13 @@ #include #include +#include "enumeration_types.hpp" #include namespace vsomeip_v3 { namespace trace { -typedef std::function filter_func_t; +using filter_func_t = std::function; class channel_impl : public channel { public: @@ -26,6 +27,10 @@ public: std::string get_id() const; std::string get_name() const; + filter_id_t add_filter( + const match_t &_match, + filter_type_e _type); + filter_id_t add_filter( const match_t &_match, bool _is_positive); @@ -34,24 +39,32 @@ public: const std::vector &_matches, bool _is_positive); + filter_id_t add_filter( + const std::vector &_matches, + filter_type_e _type); + filter_id_t add_filter( const match_t &_from, const match_t &_to, bool _is_positive); + filter_id_t add_filter( + const match_t &_from, const match_t &_to, + filter_type_e _type); + void remove_filter( filter_id_t _id); - bool matches(service_t _service, instance_t _instance, method_t _method); + std::pair matches(service_t _service, instance_t _instance, method_t _method); private: - filter_id_t add_filter_intern(const filter_func_t& _func, bool _is_positive); + filter_id_t add_filter_intern(const filter_func_t& _func, filter_type_e _type); std::string id_; std::string name_; std::atomic current_filter_id_; - std::map positive_; + std::map> positive_; std::map negative_; std::mutex mutex_; // protects positive_ & negative_ }; diff --git a/implementation/tracing/include/connector_impl.hpp b/implementation/tracing/include/connector_impl.hpp index 8274b9f..e5c90d2 100644 --- a/implementation/tracing/include/connector_impl.hpp +++ b/implementation/tracing/include/connector_impl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -7,8 +7,10 @@ #define VSOMEIP_V3_TRACE_CONNECTOR_HPP_ #ifdef USE_DLT +#ifndef ANDROID #include #endif +#endif #include #include @@ -58,7 +60,7 @@ public: VSOMEIP_EXPORT std::shared_ptr get_channel(const std::string &_id) const; VSOMEIP_EXPORT void trace(const byte_t *_header, uint16_t _header_size, - const byte_t *_data, uint16_t _data_size); + const byte_t *_data, uint32_t _data_size); private: bool is_enabled_; @@ -67,10 +69,14 @@ private: std::map> channels_; mutable std::mutex channels_mutex_; + std::shared_ptr get_channel_impl(const std::string &_id) const; + #ifdef USE_DLT +#ifndef ANDROID std::map> contexts_; mutable std::mutex contexts_mutex_; #endif +#endif }; diff --git a/implementation/tracing/include/defines.hpp b/implementation/tracing/include/defines.hpp index 022f42f..fd5e8f8 100644 --- a/implementation/tracing/include/defines.hpp +++ b/implementation/tracing/include/defines.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/tracing/include/enumeration_types.hpp b/implementation/tracing/include/enumeration_types.hpp index 3f83586..9f5f6e8 100644 --- a/implementation/tracing/include/enumeration_types.hpp +++ b/implementation/tracing/include/enumeration_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -11,7 +11,8 @@ namespace trace { enum class filter_type_e : uint8_t { NEGATIVE = 0x00, - POSITIVE = 0x01 + POSITIVE = 0x01, + HEADER_ONLY = 0x02 }; } // namespace trace diff --git a/implementation/tracing/include/header.hpp b/implementation/tracing/include/header.hpp index e3dc4c1..190a15f 100644 --- a/implementation/tracing/include/header.hpp +++ b/implementation/tracing/include/header.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/tracing/src/channel_impl.cpp b/implementation/tracing/src/channel_impl.cpp index c0bc391..26dccd3 100644 --- a/implementation/tracing/src/channel_impl.cpp +++ b/implementation/tracing/src/channel_impl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2017-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -24,6 +24,14 @@ std::string channel_impl::get_name() const { filter_id_t channel_impl::add_filter( const match_t &_match, bool _is_positive) { + filter_type_e its_filter_type = (_is_positive ? + filter_type_e::POSITIVE : filter_type_e::NEGATIVE); + + return (add_filter(_match, its_filter_type)); +} + +filter_id_t channel_impl::add_filter( + const match_t &_match, filter_type_e _type) { // Create a filter function std::function its_filter_func; @@ -86,11 +94,19 @@ filter_id_t channel_impl::add_filter( } } - return add_filter_intern(its_filter_func, _is_positive); + return add_filter_intern(its_filter_func, _type); } filter_id_t channel_impl::add_filter( const std::vector &_matches, bool _is_positive) { + filter_type_e its_filter_type = (_is_positive ? + filter_type_e::POSITIVE : filter_type_e::NEGATIVE); + + return (add_filter(_matches, its_filter_type)); +} + +filter_id_t channel_impl::add_filter( + const std::vector &_matches, filter_type_e _type) { bool has_service(false); bool has_instance(false); bool has_method(false); @@ -197,11 +213,11 @@ filter_id_t channel_impl::add_filter( } } - return add_filter_intern(its_filter_func, _is_positive); + return add_filter_intern(its_filter_func, _type); } filter_id_t channel_impl::add_filter( - const match_t &_from, const match_t &_to, bool _is_positive) { + const match_t &_from, const match_t &_to, filter_type_e _type) { // Check usage of ANY_* which is forbidden here if (std::get<0>(_from) == ANY_SERVICE || @@ -222,7 +238,15 @@ filter_id_t channel_impl::add_filter( && std::get<2>(_from) <= _m && _m <= std::get<2>(_to)); }; - return add_filter_intern(its_filter_func, _is_positive); + return add_filter_intern(its_filter_func, _type); +} + +filter_id_t channel_impl::add_filter( + const match_t &_from, const match_t &_to, bool _is_positive) { + filter_type_e its_filter_type = (_is_positive ? + filter_type_e::POSITIVE : filter_type_e::NEGATIVE); + + return (add_filter(_from, _to, its_filter_type)); } void channel_impl::remove_filter(filter_id_t _id) { @@ -231,42 +255,52 @@ void channel_impl::remove_filter(filter_id_t _id) { negative_.erase(_id); } -filter_id_t channel_impl::add_filter_intern(const filter_func_t& _func, bool _is_positive) { +filter_id_t channel_impl::add_filter_intern(const filter_func_t& _func, filter_type_e _type) { filter_id_t its_id = current_filter_id_.fetch_add(1); std::lock_guard its_lock(mutex_); - if (_is_positive) - positive_[its_id] = _func; - else - negative_[its_id] = _func; + switch(_type) { + case (filter_type_e::NEGATIVE) : + negative_[its_id] = _func; + break; + case (filter_type_e::HEADER_ONLY) : + positive_[its_id] = std::make_pair(_func, false); + break; + default : + positive_[its_id] = std::make_pair(_func, true); + } return its_id; } -bool channel_impl::matches( +std::pair channel_impl::matches( service_t _service, instance_t _instance, method_t _method) { std::lock_guard its_lock(mutex_); // If a negative filter matches --> drop! for (auto &its_filter : negative_) { - if (its_filter.second(_service, _instance, _method)) { - return false; - } + if (its_filter.second(_service, _instance, _method)) + return std::make_pair(false, false); } - // If no positive filter is defined --> forward! - if (positive_.size() == 0) - return true; - - // If a positive filter matches --> forward! + // If a positive/header-only filter matches --> forward! + bool has_positive(false); for (auto &its_filter : positive_) { - if (its_filter.second(_service, _instance, _method)) { - return true; - } + if (its_filter.second.first(_service, _instance, _method)) + return std::make_pair(true, its_filter.second.second); + + // If we have a positive filter that is no header-only + // filter, set the flag + if (its_filter.second.second) + has_positive = true; } - // drop! - return false; + // If no positive filter is defined --> forward! + if (!has_positive) + return std::make_pair(true, true); + + // Default --> Drop! + return std::make_pair(false, false); } } // namespace trace diff --git a/implementation/tracing/src/connector_impl.cpp b/implementation/tracing/src/connector_impl.cpp index f71c92e..2f93bd0 100644 --- a/implementation/tracing/src/connector_impl.cpp +++ b/implementation/tracing/src/connector_impl.cpp @@ -1,10 +1,16 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include #include +#include +#include +#include +#include +#include +#include #include "../include/channel_impl.hpp" #include "../include/connector_impl.hpp" @@ -12,6 +18,20 @@ #include "../../configuration/include/trace.hpp" #include "../../utility/include/byteorder.hpp" +#ifdef ANDROID +#include + +#ifdef ALOGI +#undef ALOGI +#endif + +#define ALOGI(LOG_TAG, ...) ((void)ALOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) +#ifndef LOGE +#define LOGI ALOGI +#endif + +#endif + namespace vsomeip_v3 { namespace trace { @@ -30,6 +50,7 @@ connector_impl::connector_impl() : = std::make_shared(VSOMEIP_TC_DEFAULT_CHANNEL_ID, VSOMEIP_TC_DEFAULT_CHANNEL_NAME); #ifdef USE_DLT +#ifndef ANDROID std::shared_ptr its_default_context = std::make_shared(); @@ -38,6 +59,7 @@ connector_impl::connector_impl() : VSOMEIP_TC_DEFAULT_CHANNEL_ID, VSOMEIP_TC_DEFAULT_CHANNEL_NAME, DLT_LOG_INFO, DLT_TRACE_STATUS_ON); #endif +#endif } connector_impl::~connector_impl() { @@ -60,14 +82,14 @@ void connector_impl::configure(const std::shared_ptr &_configuration for (auto &its_filter : _configuration->filters_) { for (auto &its_channel : its_filter->channels_) { - std::shared_ptr its_channel_ptr = get_channel(its_channel); + auto its_channel_ptr = get_channel_impl(its_channel); if (its_channel_ptr) { if (its_filter->is_range_) { its_channel_ptr->add_filter(its_filter->matches_[0], - its_filter->matches_[1], its_filter->is_positive_); + its_filter->matches_[1], its_filter->ftype_); } else { its_channel_ptr->add_filter(its_filter->matches_, - its_filter->is_positive_); + its_filter->ftype_); } } } @@ -82,8 +104,10 @@ void connector_impl::configure(const std::shared_ptr &_configuration void connector_impl::reset() { #ifdef USE_DLT +#ifndef ANDROID std::lock_guard its_contexts_lock(contexts_mutex_); contexts_.clear(); +#endif #endif // reset to default std::lock_guard its_lock_channels(channels_mutex_); @@ -131,11 +155,13 @@ std::shared_ptr connector_impl::add_channel( // register context #ifdef USE_DLT +#ifndef ANDROID std::lock_guard its_contexts_lock(contexts_mutex_); std::shared_ptr its_context = std::make_shared(); contexts_[_id] = its_context; DLT_REGISTER_CONTEXT_LL_TS(*(its_context.get()), _id.c_str(), _name.c_str(), DLT_LOG_INFO, DLT_TRACE_STATUS_ON); +#endif #endif return its_channel; @@ -152,11 +178,13 @@ bool connector_impl::remove_channel(const trace_channel_t &_id) { if (has_removed) { // unregister context #ifdef USE_DLT +#ifndef ANDROID std::lock_guard its_contexts_lock(contexts_mutex_); auto its_context = contexts_.find(_id); if (its_context != contexts_.end()) { DLT_UNREGISTER_CONTEXT(*(its_context->second.get())); } +#endif #endif } @@ -169,16 +197,27 @@ std::shared_ptr connector_impl::get_channel(const std::string &_id) con return (its_channel != channels_.end() ? its_channel->second : nullptr); } +std::shared_ptr connector_impl::get_channel_impl(const std::string &_id) const { + std::lock_guard its_channels_lock(channels_mutex_); + auto its_channel = channels_.find(_id); + return (its_channel != channels_.end() ? its_channel->second : nullptr); +} + void connector_impl::trace(const byte_t *_header, uint16_t _header_size, - const byte_t *_data, uint16_t _data_size) { -#ifdef USE_DLT + const byte_t *_data, uint32_t _data_size) { + +#if USE_DLT if (!is_enabled_) return; if (_data_size == 0) return; // no data - if (is_sd_message(_data, _data_size) && !is_sd_enabled_) + // Clip + const uint16_t its_data_size + = uint16_t(_data_size > USHRT_MAX ? USHRT_MAX : _data_size); + + if (is_sd_message(_data, its_data_size) && !is_sd_enabled_) return; // tracing of service discovery messages is disabled! service_t its_service = VSOMEIP_BYTES_TO_WORD( @@ -197,19 +236,54 @@ void connector_impl::trace(const byte_t *_header, uint16_t _header_size, // Forward to channel if the filter set of the channel allows std::lock_guard its_channels_lock(channels_mutex_); - std::lock_guard its_contexts_lock(contexts_mutex_); + #ifndef ANDROID + std::lock_guard its_contexts_lock(contexts_mutex_); + #endif for (auto its_channel : channels_) { - if (its_channel.second->matches(its_service, its_instance, its_method)) { - auto its_context = contexts_.find(its_channel.second->get_id()); - if (its_context != contexts_.end()) { - DLT_TRACE_NETWORK_SEGMENTED(*(its_context->second.get()), - DLT_NW_TRACE_IPC, - _header_size, static_cast(const_cast(_header)), - _data_size, static_cast(const_cast(_data))); - } else { - // This should never happen! - VSOMEIP_ERROR << "tracing: found channel without DLT context!"; - } + auto ftype = its_channel.second->matches(its_service, its_instance, its_method); + if (ftype.first) { + #ifndef ANDROID + auto its_context = contexts_.find(its_channel.second->get_id()); + if (its_context != contexts_.end()) { + try { + if (ftype.second) { + //Positive Filter + DLT_TRACE_NETWORK_SEGMENTED(*(its_context->second.get()), + DLT_NW_TRACE_IPC, + _header_size, static_cast(const_cast(_header)), + its_data_size, static_cast(const_cast(_data))); + } else { + //Header-Only Filter + DLT_TRACE_NETWORK_TRUNCATED(*(its_context->second.get()), + DLT_NW_TRACE_IPC, + _header_size, static_cast(const_cast(_header)), + VSOMEIP_FULL_HEADER_SIZE, + static_cast(const_cast(_data))); + } + } catch (const std::exception& e) { + VSOMEIP_INFO << "connector_impl::trace: " + << "Exception caught when trying to log a trace with DLT. " + << e.what(); + } + } else { + // This should never happen! + VSOMEIP_ERROR << "tracing: found channel without DLT context!"; + } + #else + std::stringstream ss; + ss << "TC:"; + for(int i = 0; i < _header_size; i++) { + ss << ' ' << std::setfill('0') << std::setw(2) << std::hex << int(_header[i]); + } + if (ftype.second) + _data_size = VSOMEIP_FULL_HEADER_SIZE; + for(int i = 0; i < its_data_size; i++) { + ss << ' ' << std::setfill('0') << std::setw(2) << std::hex << int(_data[i]); + } + std::string app = runtime::get_property("LogApplication"); + + ALOGI(app.c_str(), ss.str().c_str()); + #endif } } #else diff --git a/implementation/tracing/src/header.cpp b/implementation/tracing/src/header.cpp index 0940e59..bea82c3 100644 --- a/implementation/tracing/src/header.cpp +++ b/implementation/tracing/src/header.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/utility/include/byteorder.hpp b/implementation/utility/include/byteorder.hpp index ad7f752..deda45c 100644 --- a/implementation/utility/include/byteorder.hpp +++ b/implementation/utility/include/byteorder.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,9 +6,9 @@ #ifndef VSOMEIP_V3_BYTEORDER_HPP #define VSOMEIP_V3_BYTEORDER_HPP -#if defined(LINUX) +#if defined(__linux__) #include -#elif defined(FREEBSD) +#elif defined(__freebsd__) #include #else // TEST IF THERE COULD BE AN ERROR! @@ -38,8 +38,6 @@ #define VSOMEIP_BYTES_TO_WORD(x0, x1) (uint16_t((x1) << 8 | (x0))) #define VSOMEIP_BYTES_TO_LONG(x0, x1, x2, x3) (uint32_t((x3) << 24 | (x2) << 16 | (x1) << 8 | (x0))) -#define VSOMEIP_WORDS_TO_LONG(x0, x1) (uint32_t((x1) << 16 | (x0))) - #define VSOMEIP_WORD_BYTE0(x) (uint8_t((x) >> 8)) #define VSOMEIP_WORD_BYTE1(x) (uint8_t((x) & 0xFF)) @@ -48,8 +46,8 @@ #define VSOMEIP_LONG_BYTE2(x) (uint8_t(((x) >> 8) & 0xFF)) #define VSOMEIP_LONG_BYTE3(x) (uint8_t((x) & 0xFF)) -#define VSOMEIP_LONG_WORD0(x) (uint16_t(((x) >> 16) & 0xFFFF)) -#define VSOMEIP_LONG_WORD1(x) (uint16_t((x) & 0xFFFF)) +#define VSOMEIP_LONG_WORD0(x) (uint16_t((((x) >> 16) & 0xFFFF)) +#define VSOMEIP_LONG_WORD1(x) (uint16_t(((x) & 0xFFFF)) #else diff --git a/implementation/utility/include/criticalsection.hpp b/implementation/utility/include/criticalsection.hpp index 2040b74..762c821 100644 --- a/implementation/utility/include/criticalsection.hpp +++ b/implementation/utility/include/criticalsection.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/utility/include/utility.hpp b/implementation/utility/include/utility.hpp index 359bc7c..970fb0f 100644 --- a/implementation/utility/include/utility.hpp +++ b/implementation/utility/include/utility.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,11 +6,12 @@ #ifndef VSOMEIP_V3_UTILITY_HPP #define VSOMEIP_V3_UTILITY_HPP +#include +#include #include -#include #include +#include #include -#include #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN @@ -19,6 +20,8 @@ #include #include +#include + #include "criticalsection.hpp" namespace vsomeip_v3 { @@ -36,7 +39,9 @@ public: } static inline bool is_request(message_type_e _type) { - return (_type < message_type_e::MT_NOTIFICATION); + return ((_type < message_type_e::MT_NOTIFICATION) + || (_type >= message_type_e::MT_REQUEST_ACK + && _type <= message_type_e::MT_REQUEST_NO_RETURN_ACK)); } static inline bool is_request_no_return(std::shared_ptr _message) { @@ -68,10 +73,6 @@ public: return _type == message_type_e::MT_ERROR; } - static inline bool is_event(byte_t _data) { - return (0x80 & _data) > 0; - } - static inline bool is_notification(byte_t _type) { return (is_notification(static_cast(_type))); } @@ -90,19 +91,20 @@ public: static uint32_t get_payload_size(const byte_t *_data, uint32_t _size); - static bool is_routing_manager(const std::shared_ptr &_config); - static void remove_lockfile(const std::shared_ptr &_config); + static bool is_routing_manager(const std::string &_network); + static void remove_lockfile(const std::string &_network); static bool exists(const std::string &_path); static bool VSOMEIP_IMPORT_EXPORT is_file(const std::string &_path); static bool VSOMEIP_IMPORT_EXPORT is_folder(const std::string &_path); - static const std::string get_base_path(const std::shared_ptr &_config); + static std::string get_base_path(const std::string &_network); static client_t request_client_id(const std::shared_ptr &_config, const std::string &_name, client_t _client); - static void release_client_id(client_t _client); - static std::set get_used_client_ids(); - static void reset_client_ids(); + static void release_client_id(const std::string &_network, + client_t _client); + static std::set get_used_client_ids(const std::string &_network); + static void reset_client_ids(const std::string &_network); static inline bool is_valid_message_type(message_type_e _type) { return (_type == message_type_e::MT_REQUEST @@ -129,27 +131,52 @@ public: || _code == return_code_e::E_WRONG_PROTOCOL_VERSION || _code == return_code_e::E_WRONG_INTERFACE_VERSION || _code == return_code_e::E_MALFORMED_MESSAGE - || _code == return_code_e::E_WRONG_MESSAGE_TYPE - || (static_cast(_code) >= 0x20 - && static_cast(_code) <= 0x5E)); + || _code == return_code_e::E_WRONG_MESSAGE_TYPE); + } + + static inline bool compare(const vsomeip_sec_client_t &_lhs, + const vsomeip_sec_client_t &_rhs) { + + bool is_equal(false); + if (_lhs.client_type == _rhs.client_type) { + switch (_lhs.client_type) { + case VSOMEIP_CLIENT_INVALID: + is_equal = true; + break; + case VSOMEIP_CLIENT_UDS: + is_equal = (_lhs.client.uds_client.user == _rhs.client.uds_client.user + && _lhs.client.uds_client.group == _rhs.client.uds_client.group); + break; + case VSOMEIP_CLIENT_TCP: + is_equal = (_lhs.client.ip_client.ip == _rhs.client.ip_client.ip + && _lhs.client.ip_client.port == _rhs.client.ip_client.port); + break; + default: + break; + } + } + return (is_equal); } private: - static std::uint16_t get_max_client_number(const std::shared_ptr &_config); + struct data_t { + data_t(); - static std::mutex mutex__; - static client_t next_client__; - static std::map used_clients__; + client_t next_client_; + std::map used_clients_; #ifdef _WIN32 - static HANDLE lock_handle__; -#else - static int lock_fd__; -#endif -#ifndef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS - static bool is_checked__; + HANDLE lock_handle_; #else - static std::set is_checked__; + int lock_fd_; #endif + }; + +private: + static std::uint16_t get_max_client_number( + const std::shared_ptr &_config); + + static std::mutex mutex__; + static std::map data__; // network --> data }; } // namespace vsomeip_v3 diff --git a/implementation/utility/src/criticalsection.cpp b/implementation/utility/src/criticalsection.cpp index 78b0b5c..197ca4d 100644 --- a/implementation/utility/src/criticalsection.cpp +++ b/implementation/utility/src/criticalsection.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/implementation/utility/src/utility.cpp b/implementation/utility/src/utility.cpp index 139faef..a3ed5d1 100644 --- a/implementation/utility/src/utility.cpp +++ b/implementation/utility/src/utility.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -32,18 +32,16 @@ namespace vsomeip_v3 { std::mutex utility::mutex__; -client_t utility::next_client__(VSOMEIP_CLIENT_UNSET); -std::map utility::used_clients__; +std::map utility::data__; + +utility::data_t::data_t() + : next_client_(VSOMEIP_CLIENT_UNSET), #ifdef _WIN32 -HANDLE utility::lock_handle__(INVALID_HANDLE_VALUE); -#else -int utility::lock_fd__(-1); -#endif -#ifndef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS -bool utility::is_checked__(false); + lock_handle_(INVALID_HANDLE_VALUE) #else -std::set utility::is_checked__; + lock_fd_(-1) #endif +{} uint64_t utility::get_message_size(const byte_t *_data, size_t _size) { uint64_t its_size(0); @@ -63,55 +61,45 @@ uint32_t utility::get_payload_size(const byte_t *_data, uint32_t _size) { return (its_size); } -bool utility::is_routing_manager(const std::shared_ptr &_config) { +bool utility::is_routing_manager(const std::string &_network) { // Only the first caller can become routing manager. // Therefore, subsequent calls can be immediately answered... std::lock_guard its_lock(mutex__); -#ifndef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS - if (is_checked__) - return false; + if (data__.find(_network) != data__.end()) + return (false); - is_checked__ = true; -#else - if (is_checked__.find(_config->get_network()) != is_checked__.end()) - return false; + auto r = data__.insert(std::make_pair(_network, data_t())); + if (!r.second) + return (false); - is_checked__.insert(_config->get_network()); -#endif #ifdef _WIN32 wchar_t its_tmp_folder[MAX_PATH]; if (GetTempPathW(MAX_PATH, its_tmp_folder)) { std::wstring its_lockfile(its_tmp_folder); - std::string its_network(_config->get_network() + ".lck"); + std::string its_network(_network + ".lck"); its_lockfile.append(its_network.begin(), its_network.end()); - lock_handle__ = CreateFileW(its_lockfile.c_str(), GENERIC_READ, 0, NULL, CREATE_NEW, 0, NULL); - if (lock_handle__ == INVALID_HANDLE_VALUE) { + r.first->second.lock_handle_ = CreateFileW(its_lockfile.c_str(), GENERIC_READ, 0, NULL, CREATE_NEW, 0, NULL); + if (r.first->second.lock_handle_ == INVALID_HANDLE_VALUE) { VSOMEIP_ERROR << __func__ << ": CreateFileW failed: " << std::hex << GetLastError(); } } else { VSOMEIP_ERROR << __func__ << ": Could not get temp folder: " << std::hex << GetLastError(); - lock_handle__ = INVALID_HANDLE_VALUE; + r.first->second.lock_handle_ = INVALID_HANDLE_VALUE; } - return (lock_handle__ != INVALID_HANDLE_VALUE); + return (r.first->second.lock_handle_ != INVALID_HANDLE_VALUE); #else - std::string its_base_path(VSOMEIP_BASE_PATH + _config->get_network()); -#ifdef __ANDROID__ // NDK - const char *env_base_path = getenv(VSOMEIP_ENV_BASE_PATH); - if (nullptr != env_base_path) { - its_base_path = {env_base_path + _config->get_network()}; - } -#endif + std::string its_base_path(VSOMEIP_BASE_PATH + _network); std::string its_lockfile(its_base_path + ".lck"); int its_lock_ctrl(-1); struct flock its_lock_data = { F_WRLCK, SEEK_SET, 0, 0, 0 }; - lock_fd__ = open(its_lockfile.c_str(), O_WRONLY | O_CREAT, S_IWUSR | S_IWGRP); - if (-1 != lock_fd__) { + r.first->second.lock_fd_ = open(its_lockfile.c_str(), O_WRONLY | O_CREAT, S_IWUSR | S_IWGRP); + if (-1 != r.first->second.lock_fd_) { its_lock_data.l_pid = getpid(); - its_lock_ctrl = fcntl(lock_fd__, F_SETLK, &its_lock_data); + its_lock_ctrl = fcntl(r.first->second.lock_fd_, F_SETLK, &its_lock_data); } else { VSOMEIP_ERROR << __func__ << ": Could not open " << its_lockfile << ": " << std::strerror(errno); @@ -121,26 +109,23 @@ bool utility::is_routing_manager(const std::shared_ptr &_config) #endif } -void utility::remove_lockfile(const std::shared_ptr &_config) { +void utility::remove_lockfile(const std::string &_network) { std::lock_guard its_lock(mutex__); -#ifndef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS - if (!is_checked__) // No need to do anything as automatic - return; -#else - if (is_checked__.find(_config->get_network()) == is_checked__.end()) // No need to do anything as automatic + + auto r = data__.find(_network); + if (r == data__.end()) // No need to do anything as automatic return; -#endif #ifdef _WIN32 - if (lock_handle__ != INVALID_HANDLE_VALUE) { - if (CloseHandle(lock_handle__) == 0) { + if (r->second.lock_handle_ != INVALID_HANDLE_VALUE) { + if (CloseHandle(r->second.lock_handle_) == 0) { VSOMEIP_ERROR << __func__ << ": CloseHandle failed." << std::hex << GetLastError(); } wchar_t its_tmp_folder[MAX_PATH]; if (GetTempPathW(MAX_PATH, its_tmp_folder)) { std::wstring its_lockfile(its_tmp_folder); - std::string its_network(_config->get_network() + ".lck"); + std::string its_network(_network + ".lck"); its_lockfile.append(its_network.begin(), its_network.end()); if (DeleteFileW(its_lockfile.c_str()) == 0) { VSOMEIP_ERROR << __func__ << ": DeleteFileW failed: " @@ -153,17 +138,11 @@ void utility::remove_lockfile(const std::shared_ptr &_config) { } } #else - std::string its_base_path(VSOMEIP_BASE_PATH + _config->get_network()); -#ifdef __ANDROID__ // NDK - const char *env_base_path = getenv(VSOMEIP_ENV_BASE_PATH); - if (nullptr != env_base_path) { - its_base_path = {env_base_path + _config->get_network()}; - } -#endif + std::string its_base_path(VSOMEIP_BASE_PATH + _network); std::string its_lockfile(its_base_path + ".lck"); - if (lock_fd__ != -1) { - if (close(lock_fd__) == -1) { + if (r->second.lock_fd_ != -1) { + if (close(r->second.lock_fd_) == -1) { VSOMEIP_ERROR << __func__ << ": Could not close lock_fd__" << std::strerror(errno); } @@ -173,11 +152,7 @@ void utility::remove_lockfile(const std::shared_ptr &_config) { << ": " << std::strerror(errno); } #endif -#ifndef VSOMEIP_ENABLE_CONFIGURATION_OVERLAYS - is_checked__ = false; -#else - is_checked__.erase(_config->get_network()); -#endif + data__.erase(_network); } bool utility::exists(const std::string &_path) { @@ -203,19 +178,8 @@ bool utility::is_folder(const std::string &_path) { return false; } -const std::string utility::get_base_path( - const std::shared_ptr &_config) { -#ifdef __ANDROID__ // NDK - const char *env_base_path = getenv(VSOMEIP_ENV_BASE_PATH); - if (nullptr != env_base_path) { - std::string its_base_path(env_base_path + _config->get_network()); - return std::string(env_base_path + _config->get_network() + "-"); - } else { - return std::string(VSOMEIP_BASE_PATH + _config->get_network() + "-"); - } -#else - return std::string(VSOMEIP_BASE_PATH + _config->get_network() + "-"); -#endif +std::string utility::get_base_path(const std::string &_network) { + return std::string(VSOMEIP_BASE_PATH + _network + "-"); } client_t @@ -232,21 +196,25 @@ utility::request_client_id( static const client_t its_biggest_client = its_masked_diagnosis_address | its_client_mask; static const client_t its_smallest_client = its_masked_diagnosis_address; - if (next_client__ == VSOMEIP_CLIENT_UNSET) { - next_client__ = its_smallest_client; + auto r = data__.find(_config->get_network()); + if (r == data__.end()) + return (VSOMEIP_CLIENT_UNSET); + + if (r->second.next_client_ == VSOMEIP_CLIENT_UNSET) { + r->second.next_client_ = its_smallest_client; } if (_client != VSOMEIP_CLIENT_UNSET) { // predefined client identifier - const auto its_iterator = used_clients__.find(_client); - if (its_iterator == used_clients__.end()) { // unused identifier - used_clients__[_client] = _name; - return _client; + const auto its_iterator = r->second.used_clients_.find(_client); + if (its_iterator == r->second.used_clients_.end()) { // unused identifier + r->second.used_clients_[_client] = _name; + return (_client); } else { // already in use // The name matches the assigned name --> return client // NOTE: THIS REQUIRES A CONSISTENT CONFIGURATION!!! if (its_iterator->second == _name) { - return _client; + return (_client); } VSOMEIP_WARNING << "Requested client identifier " @@ -259,49 +227,58 @@ utility::request_client_id( } } - if (next_client__ == its_biggest_client) { + if (r->second.next_client_ == its_biggest_client) { // start at beginning of client range again when the biggest client was reached - next_client__ = its_smallest_client; + r->second.next_client_ = its_smallest_client; } std::uint16_t increase_count = 0; do { - next_client__ = (next_client__ & static_cast(~its_client_mask)) // save diagnosis address bits - | (static_cast((next_client__ // set all diagnosis address bits to one + r->second.next_client_ = (r->second.next_client_ + & static_cast(~its_client_mask)) // save diagnosis address bits + | (static_cast((r->second.next_client_ // set all diagnosis address bits to one | static_cast(~its_client_mask)) + 1u) // and add one to the result & its_client_mask); // set the diagnosis address bits to zero again if (increase_count++ == its_max_num_clients) { VSOMEIP_ERROR << __func__ << " no free client IDs left! " "Max amount of possible concurrent active vsomeip " - "applications reached (" << std::dec << used_clients__.size() + "applications reached (" << std::dec << r->second.used_clients_.size() << ")."; - return VSOMEIP_CLIENT_UNSET; + return (VSOMEIP_CLIENT_UNSET); } - } while (used_clients__.find(next_client__) != used_clients__.end() - || _config->is_configured_client_id(next_client__)); + } while (r->second.used_clients_.find(r->second.next_client_) != r->second.used_clients_.end() + || _config->is_configured_client_id(r->second.next_client_)); - used_clients__[next_client__] = _name; - return next_client__; + r->second.used_clients_[r->second.next_client_] = _name; + return (r->second.next_client_); } void -utility::release_client_id(client_t _client) { +utility::release_client_id(const std::string &_network, client_t _client) { std::lock_guard its_lock(mutex__); - used_clients__.erase(_client); + auto r = data__.find(_network); + if (r != data__.end()) + r->second.used_clients_.erase(_client); } std::set -utility::get_used_client_ids() { +utility::get_used_client_ids(const std::string &_network) { std::lock_guard its_lock(mutex__); std::set its_used_clients; - for (const auto& c : used_clients__) - its_used_clients.insert(c.first); + auto r = data__.find(_network); + if (r != data__.end()) { + for (const auto& c : r->second.used_clients_) + its_used_clients.insert(c.first); + } return its_used_clients; } -void utility::reset_client_ids() { +void utility::reset_client_ids(const std::string &_network) { std::lock_guard its_lock(mutex__); - used_clients__.clear(); - next_client__ = VSOMEIP_CLIENT_UNSET; + auto r = data__.find(_network); + if (r != data__.end()) { + r->second.used_clients_.clear(); + r->second.next_client_ = VSOMEIP_CLIENT_UNSET; + } } @@ -315,7 +292,7 @@ std::uint16_t utility::get_max_client_number( #else __builtin_popcount( #endif - static_cast(~_config->get_diagnosis_mask())); + static_cast(~_config->get_diagnosis_mask())); for (int var = 0; var < bits_for_clients; ++var) { its_max_clients = static_cast(its_max_clients | (1 << var)); } diff --git a/implementation/utility/src/wrappers.cpp b/implementation/utility/src/wrappers.cpp new file mode 100644 index 0000000..1b09e8c --- /dev/null +++ b/implementation/utility/src/wrappers.cpp @@ -0,0 +1,38 @@ +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifdef __linux__ + +#include +#include + +/* + * These definitions MUST remain in the global namespace. + */ +extern "C" +{ + /* + * The real socket(2), renamed by GCC. + */ + int __real_socket(int domain, int type, int protocol) noexcept; + + /* + * Overrides socket(2) to set SOCK_CLOEXEC by default. + */ + int __wrap_socket(int domain, int type, int protocol) noexcept + { + return __real_socket(domain, type | SOCK_CLOEXEC, protocol); + } + + /* + * Overrides accept(2) to set SOCK_CLOEXEC by default. + */ + int __wrap_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) + { + return accept4(sockfd, addr, addrlen, SOCK_CLOEXEC); + } +} + +#endif diff --git a/interface/compat/vsomeip/constants.hpp b/interface/compat/vsomeip/constants.hpp index c91d037..2d14920 100644 --- a/interface/compat/vsomeip/constants.hpp +++ b/interface/compat/vsomeip/constants.hpp @@ -19,7 +19,7 @@ const ttl_t DEFAULT_TTL = 0xFFFFFF; // "until next reboot" const std::string DEFAULT_MULTICAST = "224.0.0.0"; const uint16_t DEFAULT_PORT = 30500; -const uint16_t ILLEGAL_PORT = 0; +const uint16_t ILLEGAL_PORT = 0xFFFF; const uint16_t NO_TRACE_FILTER_EXPRESSION = 0x0000; diff --git a/interface/compat/vsomeip/primitive_types.hpp b/interface/compat/vsomeip/primitive_types.hpp index 93c9960..93237d0 100644 --- a/interface/compat/vsomeip/primitive_types.hpp +++ b/interface/compat/vsomeip/primitive_types.hpp @@ -9,7 +9,7 @@ #include #include -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #endif diff --git a/interface/compat/vsomeip/trace.hpp b/interface/compat/vsomeip/trace.hpp index ebdd418..db2054a 100644 --- a/interface/compat/vsomeip/trace.hpp +++ b/interface/compat/vsomeip/trace.hpp @@ -153,29 +153,29 @@ public: */ class connector { public: - /** - * \brief Get access to the connector. - * - * \return Shared pointer to the singleton object. - */ + /** + * \brief Get access to the connector. + * + * \return Shared pointer to the singleton object. + */ static std::shared_ptr get(); virtual ~connector() {}; - /** - * \brief Add a trace channel to the connector. - * - * Creates a trace channel with the given identifier and name - * and adds it to the connector. - * - * \param _id Id of the trace channel. - * \param _name Name of the trace channel - * - * \return Shared pointer to the created trace channel or - * nullptr if the trace channel could not be created because - * another trace channel with the given identifier does - * already exist. - */ + /** + * \brief Add a trace channel to the connector. + * + * Creates a trace channel with the given identifier and name + * and adds it to the connector. + * + * \param _id Id of the trace channel. + * \param _name Name of the trace channel + * + * \return Shared pointer to the created trace channel or + * nullptr if the trace channel could not be created because + * another trace channel with the given identifier does + * already exist. + */ virtual std::shared_ptr add_channel( const std::string &_id, const std::string &_name) = 0; @@ -203,7 +203,7 @@ public: * of the default trace channel. * * \return Shared pointer to the created trace channel or - * nullptr if the trace channel does not exist. + * nullptr if the trace channel does not exist. */ virtual std::shared_ptr get_channel( const std::string &_id = VSOMEIP_TC_DEFAULT_CHANNEL_ID) const = 0; diff --git a/interface/vsomeip/application.hpp b/interface/vsomeip/application.hpp index 366ecf1..10ead3e 100644 --- a/interface/vsomeip/application.hpp +++ b/interface/vsomeip/application.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,14 +12,17 @@ #include #include +#include #include #include +#include #include #include #include namespace vsomeip_v3 { +class configuration; class configuration_public; class event; class payload; @@ -475,7 +478,7 @@ public: * \param _handler Handler function to be called on state change. * */ - virtual void register_state_handler(state_handler_t _handler) = 0; + virtual void register_state_handler(const state_handler_t &_handler) = 0; /** * @@ -517,7 +520,7 @@ public: */ virtual void register_message_handler(service_t _service, instance_t _instance, method_t _method, - message_handler_t _handler) = 0; + const message_handler_t &_handler) = 0; /** * * \brief Unregisters the message handler for the specified service @@ -559,7 +562,7 @@ public: * */ virtual void register_availability_handler(service_t _service, - instance_t _instance, availability_handler_t _handler, + instance_t _instance, const availability_handler_t &_handler, major_version_t _major = ANY_MAJOR, minor_version_t _minor = ANY_MINOR) = 0; /** @@ -599,35 +602,37 @@ public: * handler decides if the subscription is accepted or not. * */ + VSOMEIP_DEPRECATED_UID_GID virtual void register_subscription_handler(service_t _service, instance_t _instance, eventgroup_t _eventgroup, - subscription_handler_t _handler) = 0; - - /** - * - * \brief Registers an async subscription handler. - * - * A subscription handler is called whenever the subscription state of an - * eventgroup changes. The callback is called with the client identifier - * and a boolean that indicates whether the client subscribed or - * unsubscribed. - * This method offers the possibility to asynchronously accept/rejects - * subscriptions through a callback. - * - * \param _service Service identifier of service instance whose - * subscription state is to be monitored. - * \param _instance Instance identifier of service instance whose - * subscription state is to be monitored. - * \param _eventgroup Eventgroup identifier of eventgroup whose - * subscription state is to be monitored. - * \param _handler Callback that shall be called. The value passed to the - * callback passed as a parameter to this handler decides if the - * subscription is accepted or not. - * - */ - virtual void register_async_subscription_handler( - service_t _service, instance_t _instance, eventgroup_t _eventgroup, - async_subscription_handler_t _handler) = 0; + const subscription_handler_t &_handler) = 0; + + /** + * + * \brief Registers an async subscription handler. + * + * A subscription handler is called whenever the subscription state of an + * eventgroup changes. The callback is called with the client identifier + * and a boolean that indicates whether the client subscribed or + * unsubscribed. + * This method offers the possibility to asynchronously accept/rejects + * subscriptions through a callback. + * + * \param _service Service identifier of service instance whose + * subscription state is to be monitored. + * \param _instance Instance identifier of service instance whose + * subscription state is to be monitored. + * \param _eventgroup Eventgroup identifier of eventgroup whose + * subscription state is to be monitored. + * \param _handler Callback that shall be called. The value passed to the + * callback passed as a parameter to this handler decides if the + * subscription is accepted or not. + * + */ + VSOMEIP_DEPRECATED_UID_GID + virtual void register_async_subscription_handler( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + const async_subscription_handler_t &_handler) = 0; /** * @@ -742,7 +747,7 @@ public: * \param _offer_type type of offered services to be returned (OT_LOCAL = 0x00, OT_REMOTE = 0x01, OT_ALL = 0x02) * \param offered_services_handler_t handler which gets called with a vector of service instance pairs that are currently offered */ - virtual void get_offered_services_async(offer_type_e _offer_type, offered_services_handler_t _handler) = 0; + virtual void get_offered_services_async(offer_type_e _offer_type, const offered_services_handler_t &_handler) = 0; /** * @@ -769,7 +774,7 @@ public: * \param _handler A watchdog handler, pass nullptr to deactivate. * \param _interval Call interval in seconds, pass std::chrono::seconds::zero() to deactivate. */ - virtual void set_watchdog_handler(watchdog_handler_t _handler, std::chrono::seconds _interval) = 0; + virtual void set_watchdog_handler(const watchdog_handler_t &_handler, std::chrono::seconds _interval) = 0; /** * \brief Enables or disables calling of registered acceptance @@ -784,8 +789,8 @@ public: * \param _enable enable or disable calling of offer acceptance handler */ virtual void set_sd_acceptance_required(const remote_info_t& _remote, - const std::string& _path, - bool _enable) = 0; + const std::string& _path, + bool _enable) = 0; /** * \brief Enables or disables calling of registered acceptance @@ -823,7 +828,7 @@ public: * * \param _handler The handler to be called */ - virtual void register_sd_acceptance_handler(sd_acceptance_handler_t _handler) = 0; + virtual void register_sd_acceptance_handler(const sd_acceptance_handler_t &_handler) = 0; /** * \brief Registers a handler which will be called upon detection of a @@ -835,7 +840,7 @@ public: * \param _handler The handler to be called */ virtual void register_reboot_notification_handler( - reboot_notification_handler_t _handler) = 0; + const reboot_notification_handler_t &_handler) = 0; /** * \brief Registers a handler which will be called when the routing reached @@ -847,7 +852,7 @@ public: * \param _handler The handler to be called */ virtual void register_routing_ready_handler( - routing_ready_handler_t _handler) = 0; + const routing_ready_handler_t &_handler) = 0; /** * \brief Registers a handler which will be called when the routing state @@ -859,7 +864,7 @@ public: * \param _handler The handler to be called */ virtual void register_routing_state_handler( - routing_state_handler_t _handler) = 0; + const routing_state_handler_t &_handler) = 0; /** * \brief Update service configuration to offer a local service on the @@ -903,7 +908,7 @@ public: uint32_t _gid, std::shared_ptr _policy, std::shared_ptr _payload, - security_update_handler_t _handler) = 0; + const security_update_handler_t &_handler) = 0; /** * \brief Remove a security configuration for routing manager and all local clients @@ -919,7 +924,186 @@ public: */ virtual void remove_security_policy_configuration(uint32_t _uid, uint32_t _gid, - security_update_handler_t _handler) = 0; + const security_update_handler_t &_handler) = 0; + + /** + * + * \brief Registers a subscription handler. + * + * A subscription handler is called whenever the subscription state of an + * eventgroup changes. The callback is called with the client identifier + * and a boolean that indicates whether the client subscribed or + * unsubscribed. + * + * \param _service Service identifier of service instance whose + * subscription state is to be monitored. + * \param _instance Instance identifier of service instance whose + * subscription state is to be monitored. + * \param _eventgroup Eventgroup identifier of eventgroup whose + * subscription state is to be monitored. + * \param _handler Callback that shall be called. The value returned by this + * handler decides if the subscription is accepted or not. + * + */ + VSOMEIP_DEPRECATED_UID_GID + virtual void register_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + const subscription_handler_ext_t &_handler) = 0; + + /** + * + * \brief Registers an async subscription handler. + * + * A subscription handler is called whenever the subscription state of an + * eventgroup changes. The callback is called with the client identifier + * and a boolean that indicates whether the client subscribed or + * unsubscribed. + * This method offers the possibility to asynchronously accept/rejects + * subscriptions through a callback. + * + * \param _service Service identifier of service instance whose + * subscription state is to be monitored. + * \param _instance Instance identifier of service instance whose + * subscription state is to be monitored. + * \param _eventgroup Eventgroup identifier of eventgroup whose + * subscription state is to be monitored. + * \param _handler Callback that shall be called. The value passed to the + * callback passed as a parameter to this handler decides if the + * subscription is accepted or not. + * + */ + VSOMEIP_DEPRECATED_UID_GID + virtual void register_async_subscription_handler( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + const async_subscription_handler_ext_t &_handler) = 0; + + + /** + * + * \brief Subscribes to an eventgroup. + * + * A user application must call this function to subscribe to an eventgroup. + * Before calling subscribe it must register all events it interested in by + * calls to @ref request_event. The method additionally allows to specify + * a specific event. If a specific event is specified, all other events of + * the eventgroup are not received by the application. + * + * Note: For external services, providing a specific event does not change + * anything regarding the message routing. The specific event is only used + * to filter incoming events and to determine which initial events must be + * sent. + * + * \param _service Service identifier of the service that contains the + * eventgroup. + * \param _instance Instance identifier of the service that contains the + * eventgroup. + * \param _eventgroup Eventgroup identifier of the eventgroup. + * \param _major Major version number of the service. + * \param _event All (Default) or a specific event. + * \param _filter Filter configuration to decide whether or not an + * incoming event will be forwarded to the application. + */ + virtual void subscribe_with_debounce(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, + event_t _event, const debounce_filter_t &_filter) = 0; + + /** + * \brief Registers a handler which will be called upon reception of + * a remote VSOMEIP/SD message with the sending ECU's IP address and port as + * parameter + * + * This method has only an effect when called on the application acting as + * routing manager + * + * \param _handler The handler to be called + */ + virtual void register_message_acceptance_handler(const message_acceptance_handler_t &_handler) = 0; + + /** + * \brief Get the configuration additional data of an application plugin + * + * \return The configuration additional data of an application plugin + */ + virtual std::map get_additional_data( + const std::string &_plugin_name) = 0; + + + /** + * + * \brief Register a callback that is called when service instances + * availability (state) changes. + * + * This method allows for the registration of callbacks that are called + * whenever a service appears or disappears. It is possible to specify + * wildcards for service, instance and/or version. Additionally, the + * version specification is optional and defaults to DEFAULT_MAJOR + * /DEFAULT_MINOR. + * + * \param _service Service identifier of the service instance whose + * availability shall be reported. Can be set to ANY_SERVICE. + * \param _instance Instance identifier of the service instance whose + * availability shall be reported. Can be set to ANY_INSTANCE. + * \param _handler Callback to be called if availability (state) changes. + * \param _major Major service version. The parameter defaults to + * DEFAULT_MAJOR and can be set to ANY_MAJOR. + * \param _minor Minor service version. The parameter defaults to + * DEFAULT_MINOR and can be set to ANY_MINOR. + * + */ + virtual void register_availability_handler(service_t _service, + instance_t _instance, const availability_state_handler_t &_handler, + major_version_t _major = ANY_MAJOR, minor_version_t _minor = ANY_MINOR) = 0; + + /** + * + * \brief Registers a subscription handler. + * + * A subscription handler is called whenever the subscription state of an + * eventgroup changes. The callback is called with the client identifier + * and a boolean that indicates whether the client subscribed or + * unsubscribed. + * (vsomeip_sec_client_t-aware) + * + * \param _service Service identifier of service instance whose + * subscription state is to be monitored. + * \param _instance Instance identifier of service instance whose + * subscription state is to be monitored. + * \param _eventgroup Eventgroup identifier of eventgroup whose + * subscription state is to be monitored. + * \param _handler Callback that shall be called. The value returned by this + * handler decides if the subscription is accepted or not. + * + */ + virtual void register_subscription_handler(service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + const subscription_handler_sec_t &_handler) = 0; + + /** + * + * \brief Registers an async subscription handler. + * + * A subscription handler is called whenever the subscription state of an + * eventgroup changes. The callback is called with the client identifier + * and a boolean that indicates whether the client subscribed or + * unsubscribed. + * This method offers the possibility to asynchronously accept/rejects + * subscriptions through a callback. + * (vsomeip_sec_client_t-aware) + * + * \param _service Service identifier of service instance whose + * subscription state is to be monitored. + * \param _instance Instance identifier of service instance whose + * subscription state is to be monitored. + * \param _eventgroup Eventgroup identifier of eventgroup whose + * subscription state is to be monitored. + * \param _handler Callback that shall be called. The value passed to the + * callback passed as a parameter to this handler decides if the + * subscription is accepted or not. + * + */ + virtual void register_async_subscription_handler( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + async_subscription_handler_sec_t _handler) = 0; }; /** @} */ diff --git a/interface/vsomeip/constants.hpp b/interface/vsomeip/constants.hpp index 3a8201a..2b040c5 100644 --- a/interface/vsomeip/constants.hpp +++ b/interface/vsomeip/constants.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -19,13 +19,14 @@ const ttl_t DEFAULT_TTL = 0xFFFFFF; // "until next reboot" const std::string DEFAULT_MULTICAST = "224.0.0.0"; const uint16_t DEFAULT_PORT = 30500; -const uint16_t ILLEGAL_PORT = 0; +const uint16_t ILLEGAL_PORT = 0xFFFF; const uint16_t ANY_PORT = 0; const uint16_t NO_TRACE_FILTER_EXPRESSION = 0x0000; const service_t ANY_SERVICE = 0xFFFF; const instance_t ANY_INSTANCE = 0xFFFF; +const eventgroup_t ANY_EVENTGROUP = 0xFFFF; const method_t ANY_METHOD = 0xFFFF; const major_version_t ANY_MAJOR = 0xFF; const minor_version_t ANY_MINOR = 0xFFFFFFFF; diff --git a/interface/vsomeip/defines.hpp b/interface/vsomeip/defines.hpp index e10c453..6485380 100644 --- a/interface/vsomeip/defines.hpp +++ b/interface/vsomeip/defines.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,36 +6,39 @@ #ifndef VSOMEIP_V3_DEFINES_HPP_ #define VSOMEIP_V3_DEFINES_HPP_ -#define VSOMEIP_PROTOCOL_VERSION 0x1 +#include +#include + +constexpr std::uint8_t VSOMEIP_PROTOCOL_VERSION = 0x1; // 0 = unlimited, if not specified otherwise via configuration file -#define VSOMEIP_MAX_LOCAL_MESSAGE_SIZE 0 +constexpr std::size_t VSOMEIP_MAX_LOCAL_MESSAGE_SIZE = 0; // 0 = unlimited, if not specified otherwise via configuration file -#define VSOMEIP_MAX_TCP_MESSAGE_SIZE 0 -#define VSOMEIP_MAX_UDP_MESSAGE_SIZE 1416 - -#define VSOMEIP_PACKET_SIZE VSOMEIP_MAX_UDP_MESSAGE_SIZE - -#define VSOMEIP_SOMEIP_HEADER_SIZE 8 -#define VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE 8 -#define VSOMEIP_FULL_HEADER_SIZE 16 - -#define VSOMEIP_SERVICE_POS_MIN 0 -#define VSOMEIP_SERVICE_POS_MAX 1 -#define VSOMEIP_METHOD_POS_MIN 2 -#define VSOMEIP_METHOD_POS_MAX 3 -#define VSOMEIP_EVENT_POS_MIN 2 -#define VSOMEIP_EVENT_POS_MAX 3 -#define VSOMEIP_LENGTH_POS_MIN 4 -#define VSOMEIP_LENGTH_POS_MAX 7 -#define VSOMEIP_CLIENT_POS_MIN 8 -#define VSOMEIP_CLIENT_POS_MAX 9 -#define VSOMEIP_SESSION_POS_MIN 10 -#define VSOMEIP_SESSION_POS_MAX 11 -#define VSOMEIP_PROTOCOL_VERSION_POS 12 -#define VSOMEIP_INTERFACE_VERSION_POS 13 -#define VSOMEIP_MESSAGE_TYPE_POS 14 -#define VSOMEIP_RETURN_CODE_POS 15 -#define VSOMEIP_PAYLOAD_POS 16 +constexpr std::size_t VSOMEIP_MAX_TCP_MESSAGE_SIZE = 0; +constexpr std::size_t VSOMEIP_MAX_UDP_MESSAGE_SIZE = 1416; + +constexpr std::size_t VSOMEIP_PACKET_SIZE = VSOMEIP_MAX_UDP_MESSAGE_SIZE; + +constexpr std::size_t VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE = 8; +constexpr std::uint32_t VSOMEIP_SOMEIP_HEADER_SIZE = 8; +constexpr std::uint32_t VSOMEIP_FULL_HEADER_SIZE = 16; + +constexpr std::size_t VSOMEIP_SERVICE_POS_MIN = 0; +constexpr std::size_t VSOMEIP_SERVICE_POS_MAX = 1; +constexpr std::size_t VSOMEIP_METHOD_POS_MIN = 2; +constexpr std::size_t VSOMEIP_METHOD_POS_MAX = 3; +constexpr std::size_t VSOMEIP_EVENT_POS_MIN = 2; +constexpr std::size_t VSOMEIP_EVENT_POS_MAX = 3; +constexpr std::size_t VSOMEIP_LENGTH_POS_MIN = 4; +constexpr std::size_t VSOMEIP_LENGTH_POS_MAX = 7; +constexpr std::size_t VSOMEIP_CLIENT_POS_MIN = 8; +constexpr std::size_t VSOMEIP_CLIENT_POS_MAX = 9; +constexpr std::size_t VSOMEIP_SESSION_POS_MIN = 10; +constexpr std::size_t VSOMEIP_SESSION_POS_MAX = 11; +constexpr std::size_t VSOMEIP_PROTOCOL_VERSION_POS = 12; +constexpr std::size_t VSOMEIP_INTERFACE_VERSION_POS = 13; +constexpr std::size_t VSOMEIP_MESSAGE_TYPE_POS = 14; +constexpr std::size_t VSOMEIP_RETURN_CODE_POS = 15; +constexpr std::size_t VSOMEIP_PAYLOAD_POS = 16; #endif // VSOMEIP_V3_DEFINES_HPP_ diff --git a/interface/vsomeip/deprecated.hpp b/interface/vsomeip/deprecated.hpp new file mode 100644 index 0000000..9ba0235 --- /dev/null +++ b/interface/vsomeip/deprecated.hpp @@ -0,0 +1,10 @@ +#ifndef VSOMEIP_V3_DEPRECATED_HPP_ +#define VSOMEIP_V3_DEPRECATED_HPP_ + +#ifdef VSOMEIP_INTERNAL_SUPPRESS_DEPRECATED +#define VSOMEIP_DEPRECATED_UID_GID +#else +#define VSOMEIP_DEPRECATED_UID_GID [[deprecated("Use vsomeip_sec_client_t-aware functions and types instead.")]] +#endif + +#endif // VSOMEIP_V3_DEPRECATED_HPP_ diff --git a/interface/vsomeip/enumeration_types.hpp b/interface/vsomeip/enumeration_types.hpp index a6bc315..8229a89 100644 --- a/interface/vsomeip/enumeration_types.hpp +++ b/interface/vsomeip/enumeration_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -88,6 +88,13 @@ enum class reliability_type_e : uint8_t { RT_UNKNOWN = 0xFF }; +enum class availability_state_e : uint8_t { + AS_UNAVAILABLE = 0x00, // unseen + AS_OFFERED = 0x01, // seen, but not requested/not yet usable + AS_AVAILABLE = 0x02, // seen and usable + AS_UNKNOWN = 0xFF +}; + } // namespace vsomeip_v3 #endif // VSOMEIP_V3_ENUMERATION_TYPES_HPP_ diff --git a/interface/vsomeip/error.hpp b/interface/vsomeip/error.hpp index 8415d90..ecbf591 100644 --- a/interface/vsomeip/error.hpp +++ b/interface/vsomeip/error.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/function_types.hpp b/interface/vsomeip/function_types.hpp index 31ef9d5..6103025 100644 --- a/interface/vsomeip/function_types.hpp +++ b/interface/vsomeip/function_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/handler.hpp b/interface/vsomeip/handler.hpp index 7e2bbe9..f95ed7b 100644 --- a/interface/vsomeip/handler.hpp +++ b/interface/vsomeip/handler.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,7 +10,9 @@ #include #include +#include #include +#include namespace vsomeip_v3 { @@ -19,15 +21,26 @@ class message; typedef std::function< void (state_type_e) > state_handler_t; typedef std::function< void (const std::shared_ptr< message > &) > message_handler_t; typedef std::function< void (service_t, instance_t, bool) > availability_handler_t; -typedef std::function< bool (client_t, uid_t, gid_t, bool) > subscription_handler_t; +typedef std::function< void (service_t, instance_t, availability_state_e) > availability_state_handler_t; +VSOMEIP_DEPRECATED_UID_GID typedef std::function< bool (client_t, uid_t, gid_t, bool) > subscription_handler_t; +VSOMEIP_DEPRECATED_UID_GID typedef std::function< bool (client_t, uid_t, gid_t, const std::string &, bool) > subscription_handler_ext_t; typedef std::function< void (const uint16_t) > error_handler_t; typedef std::function< void (const service_t, const instance_t, const eventgroup_t, const event_t, const uint16_t) > subscription_status_handler_t; -typedef std::function< void (client_t, uid_t, gid_t, bool, std::function< void (const bool) > )> async_subscription_handler_t; +VSOMEIP_DEPRECATED_UID_GID typedef std::function< void (client_t, uid_t, gid_t, bool, + std::function< void (const bool) > )> async_subscription_handler_t; +VSOMEIP_DEPRECATED_UID_GID typedef std::function< void (client_t, uid_t, gid_t, const std::string &, bool, + std::function< void (const bool) > )> async_subscription_handler_ext_t; typedef std::function< void (const std::vector> &_services) > offered_services_handler_t; typedef std::function< void () > watchdog_handler_t; +/* + * vsomeip_sec_client_t-aware subscription handlers + */ +using subscription_handler_sec_t = std::function; +using async_subscription_handler_sec_t = std::function)>; + struct ip_address_t { union { ipv4_address_t v4_; @@ -77,11 +90,20 @@ struct remote_info_t { } }; +struct message_acceptance_t { + std::uint32_t remote_address_; + std::uint16_t local_port_; + bool is_local_; + service_t service_; + instance_t instance_; +}; + typedef std::function sd_acceptance_handler_t; typedef std::function reboot_notification_handler_t; typedef std::function routing_ready_handler_t; typedef std::function routing_state_handler_t; typedef std::function security_update_handler_t; +typedef std::function message_acceptance_handler_t; } // namespace vsomeip_v3 diff --git a/interface/vsomeip/internal/deserializable.hpp b/interface/vsomeip/internal/deserializable.hpp index ae661e5..b2a549e 100644 --- a/interface/vsomeip/internal/deserializable.hpp +++ b/interface/vsomeip/internal/deserializable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/internal/logger.hpp b/interface/vsomeip/internal/logger.hpp index db92b86..4d1f4b6 100644 --- a/interface/vsomeip/internal/logger.hpp +++ b/interface/vsomeip/internal/logger.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2020-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/internal/policy_manager.hpp b/interface/vsomeip/internal/policy_manager.hpp index 45756ec..0d610d9 100644 --- a/interface/vsomeip/internal/policy_manager.hpp +++ b/interface/vsomeip/internal/policy_manager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2019-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -6,15 +6,18 @@ #ifndef VSOMEIP_V3_POLICY_MANAGER_HPP_ #define VSOMEIP_V3_POLICY_MANAGER_HPP_ + #include +#include +#include #include namespace vsomeip_v3 { struct policy; -class policy_manager { +class VSOMEIP_IMPORT_EXPORT policy_manager { public: static std::shared_ptr get(); @@ -35,4 +38,5 @@ public: } // namespace vsomeip_v3 + #endif // VSOMEIP_V3_POLICY_MANAGER_HPP_ diff --git a/interface/vsomeip/internal/serializable.hpp b/interface/vsomeip/internal/serializable.hpp index 52540b8..8101e52 100644 --- a/interface/vsomeip/internal/serializable.hpp +++ b/interface/vsomeip/internal/serializable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/message.hpp b/interface/vsomeip/message.hpp index 0d1c5cc..e7e0b0d 100644 --- a/interface/vsomeip/message.hpp +++ b/interface/vsomeip/message.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -8,7 +8,9 @@ #include +#include #include +#include namespace vsomeip_v3 { @@ -62,12 +64,22 @@ public: /** * \brief Return uid of the message sender. */ - VSOMEIP_EXPORT virtual uid_t get_uid() const = 0; + VSOMEIP_DEPRECATED_UID_GID VSOMEIP_EXPORT virtual uid_t get_uid() const = 0; /** * \brief Return gid of the message sender. */ - VSOMEIP_EXPORT virtual gid_t get_gid() const = 0; + VSOMEIP_DEPRECATED_UID_GID VSOMEIP_EXPORT virtual gid_t get_gid() const = 0; + + /** + * \brief Return environment (hostname) of the message sender. + */ + VSOMEIP_EXPORT virtual std::string get_env() const = 0; + + /** + * \brief Return security client of the message sender. + */ + VSOMEIP_EXPORT virtual vsomeip_sec_client_t get_sec_client() const = 0; }; /** @} */ diff --git a/interface/vsomeip/message_base.hpp b/interface/vsomeip/message_base.hpp index b6efa8b..fbdceb7 100644 --- a/interface/vsomeip/message_base.hpp +++ b/interface/vsomeip/message_base.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/payload.hpp b/interface/vsomeip/payload.hpp index 3e7e45a..9b8ea95 100644 --- a/interface/vsomeip/payload.hpp +++ b/interface/vsomeip/payload.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/plugin.hpp b/interface/vsomeip/plugin.hpp index 33667a8..25ccbb2 100644 --- a/interface/vsomeip/plugin.hpp +++ b/interface/vsomeip/plugin.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -39,12 +39,7 @@ typedef create_plugin_func (*plugin_init_func)(); */ class VSOMEIP_IMPORT_EXPORT_PLUGIN plugin { public: - virtual ~plugin() -#ifndef ANDROID - {} -#else - ; -#endif + virtual ~plugin() {} virtual uint32_t get_plugin_version() const = 0; virtual const std::string &get_plugin_name() const = 0; @@ -65,15 +60,15 @@ public: type_ = _type; } - const std::string &get_plugin_name() const override { + const std::string &get_plugin_name() const { return name_; } - uint32_t get_plugin_version() const override { + uint32_t get_plugin_version() const { return version_; } - plugin_type_e get_plugin_type() const override { + plugin_type_e get_plugin_type() const { return type_; } diff --git a/interface/vsomeip/plugins/application_plugin.hpp b/interface/vsomeip/plugins/application_plugin.hpp index 90e3e64..a052aa2 100644 --- a/interface/vsomeip/plugins/application_plugin.hpp +++ b/interface/vsomeip/plugins/application_plugin.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/plugins/pre_configuration_plugin.hpp b/interface/vsomeip/plugins/pre_configuration_plugin.hpp index 6505249..5385993 100644 --- a/interface/vsomeip/plugins/pre_configuration_plugin.hpp +++ b/interface/vsomeip/plugins/pre_configuration_plugin.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2016-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2016-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/primitive_types.hpp b/interface/vsomeip/primitive_types.hpp index 26a9fd7..0a9eaa5 100644 --- a/interface/vsomeip/primitive_types.hpp +++ b/interface/vsomeip/primitive_types.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -10,7 +10,7 @@ #include #include -#ifndef _WIN32 +#if defined(__linux__) || defined(ANDROID) #include #endif @@ -41,9 +41,12 @@ typedef uint8_t interface_version_t; typedef uint8_t byte_t; typedef uint16_t diagnosis_t; +typedef uint16_t port_t; + // Addresses typedef std::array ipv4_address_t; typedef std::array ipv6_address_t; +typedef std::uint16_t port_t; typedef std::string trace_channel_t; diff --git a/interface/vsomeip/runtime.hpp b/interface/vsomeip/runtime.hpp index 513847d..e2d97c8 100644 --- a/interface/vsomeip/runtime.hpp +++ b/interface/vsomeip/runtime.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -207,6 +207,26 @@ public: * */ virtual void remove_application( const std::string &_name) = 0; + + /** + * + * \brief Creates a vsomeip application object. + * + * An application object manages service offers and requests as well as + * event subscriptions. It allows to register user application functions + * as callbacks that are called on specific events during runtime, e.g + * to react on incoming SOME/IP messages. + * An application object is identified by a unique name that is also used + * in (and therefore has to match) the configuration files of vsomeip. If + * the name is left empty, the application name is taken from the + * environment variable "VSOMEIP_APPLICATION_NAME" + * + * \param _name Name of the application on the system. + * \param _path Path to the configuration file or folder. + * + */ + virtual std::shared_ptr create_application( + const std::string &_name, const std::string &_path) = 0; }; /** @} */ diff --git a/interface/vsomeip/structured_types.hpp b/interface/vsomeip/structured_types.hpp new file mode 100644 index 0000000..059d33c --- /dev/null +++ b/interface/vsomeip/structured_types.hpp @@ -0,0 +1,66 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_STRUCTURED_TYPES_HPP_ +#define VSOMEIP_V3_STRUCTURED_TYPES_HPP_ + +#include +#include + +namespace vsomeip_v3 { + +// Messages are forwarded either because their value differs from the +// last received message (on_change) or because the specified time +// (interval) between two messages has elapsed. A message that is forwarded +// because of a changed value may reset the time until the next unchanged +// message is forwarded or not (on_change_resets_interval). By specifiying +// indexes and bit masks, the comparison that is carried out to decide whether +// or not two message values differ is configurable (ignore). +struct debounce_filter_t { + debounce_filter_t() + : on_change_(false), + on_change_resets_interval_(false), + interval_(-1) { + } + + debounce_filter_t(const debounce_filter_t &_source) + : on_change_(_source.on_change_), + on_change_resets_interval_(_source.on_change_resets_interval_), + interval_(_source.interval_), + ignore_(_source.ignore_) { + } + + inline void operator=(const debounce_filter_t &_other) { + on_change_ = _other.on_change_; + on_change_resets_interval_ = _other.on_change_resets_interval_; + interval_ = _other.interval_; + ignore_ = _other.ignore_; + } + + inline bool operator==(const debounce_filter_t &_other) const { + + return (on_change_ == _other.on_change_ + && on_change_resets_interval_ == _other.on_change_resets_interval_ + && interval_ == _other.interval_ + && ignore_ == _other.ignore_); + } + + inline bool operator!=(const debounce_filter_t &_other) const { + + return (on_change_ != _other.on_change_ + || on_change_resets_interval_ != _other.on_change_resets_interval_ + || interval_ != _other.interval_ + || ignore_ != _other.ignore_); + } + + bool on_change_; + bool on_change_resets_interval_; + int64_t interval_; + std::map ignore_; +}; + +} // namespace vsomeip_v3 + +#endif // VSOMEIP_V3_STRUCTURED_TYPES_HPP diff --git a/interface/vsomeip/trace.hpp b/interface/vsomeip/trace.hpp index cf5b7b9..016dc5a 100644 --- a/interface/vsomeip/trace.hpp +++ b/interface/vsomeip/trace.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2017-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/vsomeip.hpp b/interface/vsomeip/vsomeip.hpp index 231fa3a..f0a66c5 100644 --- a/interface/vsomeip/vsomeip.hpp +++ b/interface/vsomeip/vsomeip.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/interface/vsomeip/vsomeip_sec.h b/interface/vsomeip/vsomeip_sec.h new file mode 100644 index 0000000..88c3666 --- /dev/null +++ b/interface/vsomeip/vsomeip_sec.h @@ -0,0 +1,158 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_V3_SECURITY_VSOMEIP_SEC_H_ +#define VSOMEIP_V3_SECURITY_VSOMEIP_SEC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef uint16_t vsomeip_sec_service_id_t; +typedef uint16_t vsomeip_sec_instance_id_t; +typedef uint16_t vsomeip_sec_member_id_t; // SOME/IP method or event + +typedef uint32_t vsomeip_sec_ip_addr_t; // ip address in network byte order +typedef uint16_t vsomeip_sec_network_port_t; // network port in network byte order + +#ifndef __unix__ +typedef uint32_t uid_t; +typedef uint32_t gid_t; +#endif + +typedef struct { + uid_t user; + gid_t group; +} vsomeip_sec_uds_client_credentials_t; + +typedef struct { + vsomeip_sec_ip_addr_t ip; + vsomeip_sec_network_port_t port; +} vsomeip_sec_ip_client_credentials_t; + +typedef enum { + VSOMEIP_CLIENT_UDS, + VSOMEIP_CLIENT_TCP, + VSOMEIP_CLIENT_INVALID +} vsomeip_sec_client_type_t; + +typedef struct { + vsomeip_sec_client_type_t client_type; + union { + vsomeip_sec_uds_client_credentials_t uds_client; + vsomeip_sec_ip_client_credentials_t ip_client; + } client; +} vsomeip_sec_client_t; + +typedef enum { + VSOMEIP_SEC_OK, + VSOMEIP_SEC_PERM_DENIED +} vsomeip_sec_acl_result_t; + +typedef enum { + VSOMEIP_SEC_POLICY_OK, + VSOMEIP_SEC_POLICY_NOT_FOUND, + VSOMEIP_SEC_POLICY_INVALID +} vsomeip_sec_policy_result_t; + +/** + * Load the policy and initialize policy plugin functionality. + * This function MUST be called before any other function in this library can be called. + * It will return whether loading the policy was successful or if there was some problem + * during initialization. + * + * Please note that the policy initializer does not take any additional arguments. It is assumed + * here tha the policy plugin libraries have some out-of-bounds methods to, e.g., find the policy + * file. + * + * The function may be called multiple times (even from multiple threads) without problems. + */ + vsomeip_sec_policy_result_t vsomeip_sec_policy_initialize(); + +/** + * Authenticate connection with vSomeIP router. + * + * vSomeIP router (vsomeipd) has by definition unlimited access to other vSomeIP applications. + * Therefore, EVERY connection with the router must be authenticated and then any command from/to + * vsomeipd is implicitly allowed. + * + * This method MUST be called to ensure that the remote end is supposed to act as + * vSomeIP routing manager. + * + */ +vsomeip_sec_acl_result_t vsomeip_sec_policy_authenticate_router(const vsomeip_sec_client_t *router); + + +/* + * ### RPC + */ + +/** + * Check if a server is authorised to offer a specific service / instance + * + * vsomeip_sec_policy_is_client_allowed_to_offer checks if \p server is allowed to offer a \p + * service by the security policy. + * + * This API MUST be called by vSomeIP clients before sending requests and before + * processing responses. It and SHOULD be called at the router for every service offer before + * distributing it among the clients. + * + * @note + * Both, method calls and subscribe-notify communications are end-to-end + * authenticated. Therefore, authentication of the server at the router side is optional but + * recommended. Doing so would help to detect system missconfiguration and simplify + * application debugging. + * + * @note + * Due to asynchronous nature of SOME/IP method calls, to deliver a method response, server + * establishes a separate socket which destination client must be authenticated. This method + * does exactly that. + * + * @note + * While client access may be restricted to certain methods or events, servers are always + * allowed to offer. + */ +vsomeip_sec_acl_result_t vsomeip_sec_policy_is_client_allowed_to_offer( + const vsomeip_sec_client_t *server, + vsomeip_sec_service_id_t service, vsomeip_sec_instance_id_t instance); + + + +/** + * Check if client is allowed to request a service. + * + * This method MUST be called at the server/stub side before serving a client request. It may + * additionally be used by vsomeipd when servicing service discovery so that clients that do not + * have the permission to request a certain service cannot (even) successfully discover it. + * + */ +vsomeip_sec_acl_result_t vsomeip_sec_policy_is_client_allowed_to_request( + const vsomeip_sec_client_t *client, + vsomeip_sec_service_id_t service, vsomeip_sec_instance_id_t instance); + + +/** + * Check if client is allowed to access a specific SOME/IP method. + * + * SOME/IP does not really distinguish between methods and events. It just handles everything + * via a uint16 member identifier. The identifiers below 0x7FFF are used for methods, identifier + * starting at 0x8000 are used for events. So we just have one method to check if the client is + * allowed to interact with a specific member. + * + * This method MUST be called at the server/stub side before processing a request that triggers + * a specific method or completes event registration. + */ +vsomeip_sec_acl_result_t vsomeip_sec_policy_is_client_allowed_to_access_member( + const vsomeip_sec_client_t *client, + vsomeip_sec_service_id_t service, vsomeip_sec_instance_id_t instance, vsomeip_sec_member_id_t member); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // VSOMEIP_V3_SECURITY_VSOMEIP_SEC_H_ diff --git a/libvsomeip.yaml b/libvsomeip.yaml new file mode 100644 index 0000000..85f4ea1 --- /dev/null +++ b/libvsomeip.yaml @@ -0,0 +1,6 @@ +- name: libvsomeip + version: 3.3.0 + vendor: Lynx Team + license: + concluded: CLOSED and MPLv2 + declared: MPLv2 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b4f63c7..2121715 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,3839 +1,25 @@ -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# Copyright (C) 2015-2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -cmake_minimum_required (VERSION 2.8.1) - -# Add the gtest header files to the include files -include_directories( - . - ${gtest_SOURCE_DIR}/include -) - -set(TEST_LINK_LIBRARIES gtest) - -# Function to copy files into the build directory (or anywhere else) -# On unixoid systems this function will create symlinks instead -# SOURCE_PATH: Path to the file which should be copied -# DESTINATION_PATH: destination file -# TARGET_TO_DEPEND: The copying of the file will be added as -# a dependency to this target -function(copy_to_builddir SOURCE_PATH DESTINATION_PATH TARGET_TO_DEPEND) - if(${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR NOT ${TEST_SYMLINK_CONFIG_FILES}) - ADD_CUSTOM_COMMAND( - OUTPUT "${DESTINATION_PATH}" - COMMAND ${CMAKE_COMMAND} -E copy "${SOURCE_PATH}" "${DESTINATION_PATH}" - DEPENDS "${SOURCE_PATH}" - COMMENT "Copying \"${SOURCE_PATH}\" into build directory" - ) - else() - if(${TEST_SYMLINK_CONFIG_FILES_RELATIVE}) - ADD_CUSTOM_COMMAND( - OUTPUT "${DESTINATION_PATH}" - # Create a relative link - COMMAND ln -s -r "${SOURCE_PATH}" "${DESTINATION_PATH}" - DEPENDS "${SOURCE_PATH}" - COMMENT "Symlinking \"${SOURCE_PATH}\" into build directory" - ) - else() - ADD_CUSTOM_COMMAND( - OUTPUT "${DESTINATION_PATH}" - # Create an absolute link - COMMAND ${CMAKE_COMMAND} -E create_symlink "${SOURCE_PATH}" "${DESTINATION_PATH}" - DEPENDS "${SOURCE_PATH}" - COMMENT "Symlinking \"${SOURCE_PATH}\" into build directory" - ) - endif() - endif() - # Add a random number to the end of the string to avoid problems with - # duplicate filenames - set(FILENAME "") - get_filename_component(FILENAME ${SOURCE_PATH} NAME ) - string(RANDOM LENGTH 4 ALPHABET 0123456789 RANDOMNUMBER) - if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") - ADD_CUSTOM_TARGET(copy_${FILENAME}_${RANDOMNUMBER} - DEPENDS "${DESTINATION_PATH}" - ) - ADD_DEPENDENCIES(${TARGET_TO_DEPEND} copy_${FILENAME}_${RANDOMNUMBER}) - else() - ADD_CUSTOM_TARGET(symlink_${FILENAME}_${RANDOMNUMBER} - DEPENDS "${DESTINATION_PATH}" - ) - ADD_DEPENDENCIES(${TARGET_TO_DEPEND} symlink_${FILENAME}_${RANDOMNUMBER}) - endif() -endfunction() - -############################################################################## -# configuration-test -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_CONFIGURATION configuration-test) - - add_executable(${TEST_CONFIGURATION} - configuration_tests/configuration-test.cpp - ${PROJECT_SOURCE_DIR}/implementation/plugin/src/plugin_manager_impl.cpp - ) - target_link_libraries(${TEST_CONFIGURATION} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # The following will make sure that ${TEST_CONFIGURATION_CONFIG_FILE} is copied - # from the config folder into the test folder in the builddirectory - # This makes it possible to call the configuration test within the build directory - set(TEST_CONFIGURATION_CONFIG_FILE configuration-test.json) - set(TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE configuration-test-deprecated.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/configuration_tests/${TEST_CONFIGURATION_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CONFIGURATION_CONFIG_FILE} - ${TEST_CONFIGURATION} - ) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/configuration_tests/${TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE} - ${TEST_CONFIGURATION} - ) -endif() -############################################################################## -# application test -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_APPLICATION application_test) - - add_executable(${TEST_APPLICATION} application_tests/${TEST_APPLICATION}.cpp) - target_link_libraries(${TEST_APPLICATION} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_APPLICATION_SINGLE_PROCESS_NAME ${TEST_APPLICATION}_single_process) - add_executable(${TEST_APPLICATION_SINGLE_PROCESS_NAME} application_tests/${TEST_APPLICATION_SINGLE_PROCESS_NAME}.cpp) - target_link_libraries(${TEST_APPLICATION_SINGLE_PROCESS_NAME} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_APPLICATION_AVAILABILITY_NAME ${TEST_APPLICATION}_availability) - add_executable(${TEST_APPLICATION_AVAILABILITY_NAME} application_tests/${TEST_APPLICATION_AVAILABILITY_NAME}.cpp) - target_link_libraries(${TEST_APPLICATION_AVAILABILITY_NAME} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE ${TEST_APPLICATION}_single_process.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE} - ${TEST_APPLICATION}_single_process - ) - - set(TEST_APPLICATION_CONFIGURATION_FILE ${TEST_APPLICATION}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/application_tests/conf/${TEST_APPLICATION_CONFIGURATION_FILE}.in - ${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_CONFIGURATION_FILE} - ${TEST_APPLICATION} - ) - - set(TEST_APPLICATION_CONFIGURATION_FILE_DAEMON ${TEST_APPLICATION}_daemon.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/application_tests/conf/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON}.in - ${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} - ${TEST_APPLICATION} - ) - - set(TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE ${TEST_APPLICATION}_no_dispatch_threads.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/application_tests/conf/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE}.in - ${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} - ${TEST_APPLICATION} - ) - - set(TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON ${TEST_APPLICATION}_no_dispatch_threads_daemon.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/application_tests/conf/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON}.in - ${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} - ${TEST_APPLICATION} - ) - - set(TEST_APPLICATION_STARTER ${TEST_APPLICATION}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_STARTER} - ${TEST_APPLICATION} - ) - - set(TEST_APPLICATION_SINGLE_PROCESS_STARTER ${TEST_APPLICATION}_single_process_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} - ${TEST_APPLICATION}_single_process - ) - - set(TEST_APPLICATION_AVAILABILITY_STARTER ${TEST_APPLICATION_AVAILABILITY_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/application_tests/${TEST_APPLICATION_AVAILABILITY_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_AVAILABILITY_STARTER} - ${TEST_APPLICATION_SINGLE_PROCESS_NAME} - ) -endif() -############################################################################## -# magic-cookies-test-client -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_MAGIC_COOKIES_NAME magic_cookies_test) - - set(TEST_MAGIC_COOKIES_CLIENT ${TEST_MAGIC_COOKIES_NAME}_client) - add_executable(${TEST_MAGIC_COOKIES_CLIENT} magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT}.cpp) - target_link_libraries(${TEST_MAGIC_COOKIES_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_MAGIC_COOKIES_SERVICE ${TEST_MAGIC_COOKIES_NAME}_service) - add_executable(${TEST_MAGIC_COOKIES_SERVICE} magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE}.cpp) - target_link_libraries(${TEST_MAGIC_COOKIES_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE ${TEST_MAGIC_COOKIES_CLIENT}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/conf/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} - ${TEST_MAGIC_COOKIES_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT ${TEST_MAGIC_COOKIES_CLIENT}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT} - ${TEST_MAGIC_COOKIES_CLIENT} - ) - - set(TEST_MAGIC_COOKIES_SERVICE magic_cookies_test_service) - # Copy config file for service into $BUILDDIR/test - set(TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE ${TEST_MAGIC_COOKIES_SERVICE}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/conf/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} - ${TEST_MAGIC_COOKIES_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT ${TEST_MAGIC_COOKIES_SERVICE}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT} - ${TEST_MAGIC_COOKIES_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_MAGIC_COOKIES_STARTER ${TEST_MAGIC_COOKIES_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/magic_cookies_tests/${TEST_MAGIC_COOKIES_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_STARTER} - ${TEST_MAGIC_COOKIES_CLIENT} - ) -endif() -############################################################################## -# someip-header-factory-test -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_HEADER_FACTORY_NAME header_factory_test) - - set(TEST_HEADER_FACTORY header_factory_test) - add_executable(${TEST_HEADER_FACTORY} header_factory_tests/header_factory_test.cpp) - target_link_libraries(${TEST_HEADER_FACTORY} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ) - - ############################################################################## - # Now comes the second part of the header factory test which consists of ouf - # a client and a service both with settings file and bash scripts to start them - set(TEST_HEADER_FACTORY_CLIENT header_factory_test_client) - add_executable(${TEST_HEADER_FACTORY_CLIENT} header_factory_tests/${TEST_HEADER_FACTORY_CLIENT}.cpp) - target_link_libraries(${TEST_HEADER_FACTORY_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE ${TEST_HEADER_FACTORY_CLIENT}.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE} - ${TEST_HEADER_FACTORY_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_HEADER_FACTORY_CLIENT_START_SCRIPT ${TEST_HEADER_FACTORY_CLIENT}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_CLIENT_START_SCRIPT} - ${TEST_HEADER_FACTORY_CLIENT} - ) - - set(TEST_HEADER_FACTORY_SERVICE header_factory_test_service) - add_executable(${TEST_HEADER_FACTORY_SERVICE} header_factory_tests/${TEST_HEADER_FACTORY_SERVICE}.cpp) - target_link_libraries(${TEST_HEADER_FACTORY_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${CMAKE_THREAD_LIBS_INIT} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE ${TEST_HEADER_FACTORY_SERVICE}.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE} - ${TEST_HEADER_FACTORY_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_HEADER_FACTORY_SERVICE_START_SCRIPT ${TEST_HEADER_FACTORY_SERVICE}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_SERVICE_START_SCRIPT} - ${TEST_HEADER_FACTORY_SERVICE} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_HEADER_FACTORY_STARTER header_factory_test_send_receive_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/header_factory_tests/${TEST_HEADER_FACTORY_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_STARTER} - ${TEST_HEADER_FACTORY_CLIENT} - ) -endif() -############################################################################## -# routing-test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_LOCAL_ROUTING_NAME local_routing_test) - - set(TEST_LOCAL_ROUTING_SERVICE local_routing_test_service) - add_executable(${TEST_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_LOCAL_ROUTING_SERVICE}.cpp) - target_link_libraries(${TEST_LOCAL_ROUTING_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_LOCAL_ROUTING_SERVICE}.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${TEST_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_LOCAL_ROUTING_SERVICE}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${TEST_LOCAL_ROUTING_SERVICE} - ) - - set(TEST_LOCAL_ROUTING_CLIENT local_routing_test_client) - add_executable(${TEST_LOCAL_ROUTING_CLIENT} routing_tests/${TEST_LOCAL_ROUTING_CLIENT}.cpp) - target_link_libraries(${TEST_LOCAL_ROUTING_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_LOCAL_ROUTING_CLIENT}.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_LOCAL_ROUTING_CLIENT}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_LOCAL_ROUTING_STARTER local_routing_test_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/routing_tests/conf/${TEST_LOCAL_ROUTING_STARTER}.in - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_STARTER} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_STARTER} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - ############################################################################## - set(TEST_EXTERNAL_LOCAL_ROUTING_NAME external_local_routing_test) - set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE external_local_routing_test_service) - add_executable(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}.cpp) - target_link_libraries(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/routing_tests/conf/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start external client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT external_local_routing_test_client_external) - set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/routing_tests/conf/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_ROUTING_STARTER external_local_routing_test_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} - ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} - ) -else() - set(TEST_LOCAL_ROUTING_NAME local_routing_test) - - set(TEST_LOCAL_ROUTING_SERVICE local_routing_test_service) - add_executable(${TEST_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_LOCAL_ROUTING_SERVICE}.cpp) - target_link_libraries(${TEST_LOCAL_ROUTING_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_LOCAL_ROUTING_SERVICE}.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} - ${TEST_LOCAL_ROUTING_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_LOCAL_ROUTING_SERVICE}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} - ${TEST_LOCAL_ROUTING_SERVICE} - ) - - set(TEST_LOCAL_ROUTING_CLIENT local_routing_test_client) - add_executable(${TEST_LOCAL_ROUTING_CLIENT} routing_tests/${TEST_LOCAL_ROUTING_CLIENT}.cpp) - target_link_libraries(${TEST_LOCAL_ROUTING_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_LOCAL_ROUTING_CLIENT}.json) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_LOCAL_ROUTING_CLIENT}_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} - ${TEST_LOCAL_ROUTING_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_LOCAL_ROUTING_STARTER local_routing_test_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/routing_tests/conf/${TEST_LOCAL_ROUTING_STARTER}.bat.in - ${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_STARTER} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/routing_tests/${TEST_LOCAL_ROUTING_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_STARTER} - ${TEST_LOCAL_ROUTING_CLIENT} - ) -endif() -############################################################################## -# restart_routing-test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_RESTART_ROUTING_NAME restart_routing_test) - - set(TEST_RESTART_ROUTING_SERVICE restart_routing_test_service) - add_executable(${TEST_RESTART_ROUTING_SERVICE} restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE}.cpp) - target_link_libraries(${TEST_RESTART_ROUTING_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE ${TEST_RESTART_ROUTING_SERVICE}.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE} - ${TEST_RESTART_ROUTING_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_RESTART_ROUTING_SERVICE_START_SCRIPT ${TEST_RESTART_ROUTING_SERVICE}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_SERVICE_START_SCRIPT} - ${TEST_RESTART_ROUTING_SERVICE} - ) - - set(TEST_RESTART_ROUTING_CLIENT restart_routing_test_client) - add_executable(${TEST_RESTART_ROUTING_CLIENT} - restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT}.cpp - ) - target_link_libraries(${TEST_RESTART_ROUTING_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE ${TEST_RESTART_ROUTING_CLIENT}.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE} - ${TEST_RESTART_ROUTING_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_RESTART_ROUTING_CLIENT_START_SCRIPT ${TEST_RESTART_ROUTING_CLIENT}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_CLIENT_START_SCRIPT} - ${TEST_RESTART_ROUTING_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_RESTART_ROUTING_STARTER restart_routing_test_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/restart_routing_tests/${TEST_RESTART_ROUTING_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_STARTER} - ${TEST_RESTART_ROUTING_CLIENT} - ) - - # Copy config file for autoconfig into $BUILDDIR/test - set(TEST_RESTART_ROUTING_AUTO_CONFIG_FILE ${TEST_RESTART_ROUTING_NAME}_autoconfig.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/restart_routing_tests/${TEST_RESTART_ROUTING_AUTO_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_AUTO_CONFIG_FILE} - ${TEST_RESTART_ROUTING_CLIENT} - ) -endif() - -############################################################################## -# security test -############################################################################## - -if (${TEST_SECURITY}) - if(NOT ${TESTS_BAT}) - set(TEST_SECURITY_NAME security_test) - set(TEST_SECURITY_SERVICE security_test_service) - set(TEST_SECURITY_CLIENT security_test_client) - - add_executable(${TEST_SECURITY_SERVICE} security_tests/${TEST_SECURITY_SERVICE}.cpp) - target_link_libraries(${TEST_SECURITY_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_SECURITY_LOCAL_CONFIG_FILE ${TEST_SECURITY_NAME}_local_config.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/security_tests/conf/${TEST_SECURITY_LOCAL_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_LOCAL_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_LOCAL_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_LOCAL_CONFIG_FILE} - ${TEST_SECURITY_SERVICE} - ) - - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_SECURITY_NAME}_config_service_external_allow.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/security_tests/conf/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL}.in - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} - ${TEST_SECURITY_SERVICE} - ) - - # Copy client config file for external allow tests into $BUILDDIR/test - set(TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_SECURITY_NAME}_config_client_external_allow.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/security_tests/conf/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL}.in - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} - ${TEST_SECURITY_SERVICE} - ) - - # Copy service config file for external deny tests into $BUILDDIR/test - set(TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY ${TEST_SECURITY_NAME}_config_service_external_deny.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/security_tests/conf/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY}.in - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} - ${TEST_SECURITY_SERVICE} - ) - - # Copy client config file for external deny tests into $BUILDDIR/test - set(TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY ${TEST_SECURITY_NAME}_config_client_external_deny.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/security_tests/conf/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY}.in - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} - ${TEST_SECURITY_SERVICE} - ) - - # Copy bashscript to start local test into $BUILDDIR/test - set(TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT ${TEST_SECURITY_NAME}_local_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} - ${TEST_SECURITY_SERVICE} - ) - - # Copy bashscript to start external tests (master) into $BUILDDIR/test - set(TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT ${TEST_SECURITY_NAME}_external_master_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} - ${TEST_SECURITY_SERVICE} - ) - - # Copy bashscript to start external tests (slave) into $BUILDDIR/test - set(TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT ${TEST_SECURITY_NAME}_external_slave_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/security_tests/${TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT} - ${TEST_SECURITY_SERVICE} - ) - - add_executable(${TEST_SECURITY_CLIENT} - security_tests/${TEST_SECURITY_CLIENT}.cpp - ) - target_link_libraries(${TEST_SECURITY_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - endif() -endif() - -############################################################################## -# payload-test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_LOCAL_PAYLOAD_NAME local_payload_test) - - set(TEST_PAYLOAD_SERVICE payload_test_service) - add_executable(${TEST_PAYLOAD_SERVICE} payload_tests/${TEST_PAYLOAD_SERVICE}.cpp) - target_link_libraries(${TEST_PAYLOAD_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service into $BUILDDIR/test - set(TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE local_${TEST_PAYLOAD_SERVICE}.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - ${TEST_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT local_${TEST_PAYLOAD_SERVICE}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} - ${TEST_PAYLOAD_SERVICE} - ) - - set(TEST_PAYLOAD_CLIENT payload_test_client) - add_executable(${TEST_PAYLOAD_CLIENT} - payload_tests/${TEST_PAYLOAD_CLIENT}.cpp - payload_tests/stopwatch.cpp - ) - target_link_libraries(${TEST_PAYLOAD_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client into $BUILDDIR/test - set(TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE local_${TEST_PAYLOAD_CLIENT}.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - ${TEST_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT local_${TEST_PAYLOAD_CLIENT}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT} - ${TEST_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_LOCAL_PAYLOAD_STARTER local_payload_test_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_STARTER} - ${TEST_PAYLOAD_CLIENT} - ) - - ############################################################################## - set(TEST_EXTERNAL_LOCAL_PAYLOAD_NAME external_local_payload_test) - set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE external_local_payload_test_service) - - # Copy config file for service into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} - ${TEST_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} - ${TEST_PAYLOAD_SERVICE} - ) - - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL external_local_payload_test_client_local) - - # Copy config file for client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} - ${TEST_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT} - ${TEST_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME external_local_payload_test_client_local) - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} - ${TEST_PAYLOAD_CLIENT} - ) - ############################################################################## - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME external_local_payload_test_client_external) - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL external_local_payload_test_client_external) - - # Copy config file for client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} - ${TEST_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start client into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT} - ${TEST_PAYLOAD_CLIENT} - ) - - set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENT_EXTERNAL external_local_payload_test_service_client_external) - - # Copy bashscript to start service into $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENT_EXTERNAL}_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT} - ${TEST_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} - ${TEST_PAYLOAD_CLIENT} - ) - - ############################################################################## - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME external_local_payload_test_client_local_and_external) - set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} - ${TEST_PAYLOAD_CLIENT} - ) - - ############################################################################## - set(TEST_LOCAL_PAYLOAD_HUGE_NAME local_payload_test_huge_payload) - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_LOCAL_PAYLOAD_HUGE_STARTER ${TEST_LOCAL_PAYLOAD_HUGE_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/payload_tests/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} - ${TEST_PAYLOAD_CLIENT} - ) -endif() - -############################################################################## -# big_payload_test -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_BIG_PAYLOAD_NAME big_payload_test) - - set(TEST_BIG_PAYLOAD_SERVICE big_payload_test_service) - add_executable(${TEST_BIG_PAYLOAD_SERVICE} big_payload_tests/${TEST_BIG_PAYLOAD_SERVICE}.cpp) - target_link_libraries(${TEST_BIG_PAYLOAD_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_BIG_PAYLOAD_CLIENT big_payload_test_client) - add_executable(${TEST_BIG_PAYLOAD_CLIENT} big_payload_tests/${TEST_BIG_PAYLOAD_CLIENT}.cpp) - target_link_libraries(${TEST_BIG_PAYLOAD_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local_queue_limited.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_local_random.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_limited.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_tcp_client.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_tcp_service.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_tcp_client_limited_general.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_tcp_service_limited_general.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_tcp_client_random.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_tcp_service_random.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL ${TEST_BIG_PAYLOAD_NAME}_tcp_client_queue_limited_general.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL ${TEST_BIG_PAYLOAD_NAME}_tcp_service_queue_limited_general.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC ${TEST_BIG_PAYLOAD_NAME}_tcp_client_queue_limited_specific.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy config file for client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC ${TEST_BIG_PAYLOAD_NAME}_tcp_service_queue_limited_specific.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - # Copy config file for UDP client and service into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_udp_service.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_udp_client.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start client local to $BUILDDIR/test - set(TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_client_local_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} - ${TEST_BIG_PAYLOAD_CLIENT} - ) - - # Copy bashscript to start service local to $BUILDDIR/test - set(TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_service_local_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start client and server $BUILDDIR/test - set(TEST_LOCAL_BIG_PAYLOAD_NAME big_payload_test_local) - set(TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM big_payload_test_local_random) - set(TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED big_payload_test_local_limited) - set(TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED big_payload_test_local_queue_limited) - set(TEST_LOCAL_BIG_PAYLOAD_STARTER ${TEST_LOCAL_BIG_PAYLOAD_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start client for external test into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME big_payload_test_external) - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM big_payload_test_external_random) - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED big_payload_test_external_limited) - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL big_payload_test_external_limited_general) - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL big_payload_test_external_queue_limited_general) - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC big_payload_test_external_queue_limited_specific) - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP big_payload_test_external_udp) - set(TEST_EXTERNAL_BIG_PAYLOAD_STARTER ${TEST_EXTERNAL_BIG_PAYLOAD_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start server for external into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_NAME big_payload_test_external) - set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_service_external_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} - ${TEST_BIG_PAYLOAD_SERVICE} - ) - - # Copy bashscript to start client for external test into $BUILDDIR/test - set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_client_start.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} - ${TEST_BIG_PAYLOAD_CLIENT} - ) -endif() - -############################################################################## -# client id tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_CLIENT_ID_NAME client_id_test) - set(TEST_CLIENT_ID_SERVICE ${TEST_CLIENT_ID_NAME}_service) - add_executable(${TEST_CLIENT_ID_SERVICE} client_id_tests/${TEST_CLIENT_ID_NAME}_service.cpp) - target_link_libraries(${TEST_CLIENT_ID_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_CLIENT_ID_UTILITY ${TEST_CLIENT_ID_NAME}_utility) - add_executable(${TEST_CLIENT_ID_UTILITY} - client_id_tests/${TEST_CLIENT_ID_UTILITY}.cpp - ${PROJECT_SOURCE_DIR}/implementation/utility/src/utility.cpp) - target_link_libraries(${TEST_CLIENT_ID_UTILITY} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_same_client_ids_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_same_client_ids_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_same_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_CLIENT_ID_NAME}_same_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_CLIENT_ID_SERVICE} - ) - - set(TEST_CLIENT_ID_UTILITY_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_UTILITY_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - set(TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_511.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - - set(TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_4095.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - - set(TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_127.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - - set(TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_discontinuous_masked_511.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE} - ${TEST_CLIENT_ID_UTILITY} - ) - - # copy starter scripts into builddir - set(TEST_CLIENT_ID_MASTER_STARTER ${TEST_CLIENT_ID_NAME}_master_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_MASTER_STARTER} - ${TEST_CLIENT_ID_SERVICE} - ) - set(TEST_CLIENT_ID_SLAVE_STARTER ${TEST_CLIENT_ID_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/client_id_tests/${TEST_CLIENT_ID_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_SLAVE_STARTER} - ${TEST_CLIENT_ID_SERVICE} - ) -endif() - -############################################################################## -# subscribe notify tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_SUBSCRIBE_NOTIFY_NAME subscribe_notify_test) - set(TEST_SUBSCRIBE_NOTIFY_SERVICE ${TEST_SUBSCRIBE_NOTIFY_NAME}_service) - add_executable(${TEST_SUBSCRIBE_NOTIFY_SERVICE} subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_NAME}_service.cpp) - target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_master_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - # copy starter scripts into builddir - set(TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_master_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - set(TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_SERVICE} - ) - - # subscribe_notify_test_one_event_two_eventgroups - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME subscribe_notify_test_one_event_two_eventgroups) - - # service - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_service) - add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE}.cpp) - target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - # client - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_client) - add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT}.cpp) - target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - ) - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - ) - set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} - ) -endif() - -############################################################################## -# subscribe notify one tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_SUBSCRIBE_NOTIFY_ONE_NAME subscribe_notify_one_test) - set(TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_service) - add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_service.cpp) - target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - - # copy starter scripts into builddir - set(TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_master_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) - set(TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER} - ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} - ) -endif() - -############################################################################## -# cpu-load-test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_CPU_LOAD_NAME cpu_load_test) - - set(TEST_CPU_LOAD_SERVICE cpu_load_test_service) - add_executable(${TEST_CPU_LOAD_SERVICE} - cpu_load_tests/${TEST_CPU_LOAD_SERVICE}.cpp - cpu_load_tests/cpu_load_measurer.cpp - ) - target_link_libraries(${TEST_CPU_LOAD_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_service_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/conf/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} - ${TEST_CPU_LOAD_SERVICE} - ) - set(TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_service_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/conf/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} - ${TEST_CPU_LOAD_SERVICE} - ) - - ############################################################################## - set(TEST_CPU_LOAD_CLIENT cpu_load_test_client) - add_executable(${TEST_CPU_LOAD_CLIENT} - cpu_load_tests/${TEST_CPU_LOAD_CLIENT}.cpp - cpu_load_tests/cpu_load_measurer.cpp - ) - target_link_libraries(${TEST_CPU_LOAD_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_client_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/conf/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} - ${TEST_CPU_LOAD_CLIENT} - ) - set(TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_client_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/conf/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} - ${TEST_CPU_LOAD_CLIENT} - ) - - ############################################################################## - # copy starter scripts into builddir - set(TEST_CPU_LOAD_MASTER_STARTER ${TEST_CPU_LOAD_NAME}_master_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_MASTER_STARTER} - ${TEST_CPU_LOAD_SERVICE} - ) - set(TEST_CPU_LOAD_SLAVE_STARTER ${TEST_CPU_LOAD_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/cpu_load_tests/${TEST_CPU_LOAD_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_SLAVE_STARTER} - ${TEST_CPU_LOAD_SERVICE} - ) -endif() - -############################################################################## -# initial event tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_INITIAL_EVENT_NAME initial_event_test) - set(TEST_INITIAL_EVENT_SERVICE ${TEST_INITIAL_EVENT_NAME}_service) - add_executable(${TEST_INITIAL_EVENT_SERVICE} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_service.cpp) - target_link_libraries(${TEST_INITIAL_EVENT_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_INITIAL_EVENT_CLIENT ${TEST_INITIAL_EVENT_NAME}_client) - add_executable(${TEST_INITIAL_EVENT_CLIENT} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_client.cpp) - target_link_libraries(${TEST_INITIAL_EVENT_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_INITIAL_EVENT_AVAILABILITY_CHECKER ${TEST_INITIAL_EVENT_NAME}_availability_checker) - add_executable(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_availability_checker.cpp) - target_link_libraries(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_INITIAL_EVENT_STOP_SERVICE ${TEST_INITIAL_EVENT_NAME}_stop_service) - add_executable(${TEST_INITIAL_EVENT_STOP_SERVICE} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_stop_service.cpp) - target_link_libraries(${TEST_INITIAL_EVENT_STOP_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - # Copy config files for test into $BUILDDIR/test - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_same_client_ids_same_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_same_client_ids_same_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_same_client_ids_diff_ports_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_same_client_ids_diff_ports_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE - ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} - ${TEST_INITIAL_EVENT_SERVICE} - ) - - # copy starter scripts into builddir - set(TEST_INITIAL_EVENT_MASTER_STARTER ${TEST_INITIAL_EVENT_NAME}_master_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} - ${TEST_INITIAL_EVENT_SERVICE} - ) - set(TEST_INITIAL_EVENT_SLAVE_STARTER ${TEST_INITIAL_EVENT_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_SLAVE_STARTER} - ${TEST_INITIAL_EVENT_SERVICE} - ) -endif() - -############################################################################## -# offer tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_OFFER_NAME offer_test) - set(TEST_OFFER_SERVICE ${TEST_OFFER_NAME}_service) - add_executable(${TEST_OFFER_SERVICE} offer_tests/${TEST_OFFER_NAME}_service.cpp) - target_link_libraries(${TEST_OFFER_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_OFFER_CLIENT ${TEST_OFFER_NAME}_client) - add_executable(${TEST_OFFER_CLIENT} offer_tests/${TEST_OFFER_NAME}_client.cpp) - target_link_libraries(${TEST_OFFER_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_OFFER_SERVICE_EXTERNAL ${TEST_OFFER_NAME}_service_external) - add_executable(${TEST_OFFER_SERVICE_EXTERNAL} offer_tests/${TEST_OFFER_NAME}_service_external.cpp) - target_link_libraries(${TEST_OFFER_SERVICE_EXTERNAL} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_OFFER_SERVICE_AVAILABILITY_CHECKER ${TEST_OFFER_NAME}_service_availability_checker) - add_executable(${TEST_OFFER_SERVICE_AVAILABILITY_CHECKER} offer_tests/${TEST_OFFER_NAME}_service_availability_checker.cpp) - target_link_libraries(${TEST_OFFER_SERVICE_AVAILABILITY_CHECKER} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER ${TEST_OFFER_NAME}_external_sd_msg_sender) - add_executable(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} offer_tests/${TEST_OFFER_NAME}_external_sd_msg_sender.cpp) - target_link_libraries(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # client and service for offer test big sd msg - set(TEST_OFFER_BIG_NAME offer_test_big_sd_msg) - set(TEST_OFFER_BIG_SERVICE ${TEST_OFFER_BIG_NAME}_service) - add_executable(${TEST_OFFER_BIG_SERVICE} offer_tests/${TEST_OFFER_BIG_NAME}_service.cpp) - target_link_libraries(${TEST_OFFER_BIG_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_OFFER_BIG_CLIENT ${TEST_OFFER_BIG_NAME}_client) - add_executable(${TEST_OFFER_BIG_CLIENT} offer_tests/${TEST_OFFER_BIG_NAME}_client.cpp) - target_link_libraries(${TEST_OFFER_BIG_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # copy starter scripts into builddir - set(TEST_OFFER_LOCAL_STARTER ${TEST_OFFER_NAME}_local_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_LOCAL_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_LOCAL_STARTER} - ${TEST_OFFER_SERVICE} - ) - - # Copy config file for local test into $BUILDDIR/test - set(TEST_OFFER_LOCAL_CONFIG_FILE ${TEST_OFFER_NAME}_local.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_LOCAL_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_LOCAL_CONFIG_FILE} - ${TEST_OFFER_SERVICE} - ) - - # generate and copy json files into builddir for external test - set(TEST_OFFER_SLAVE_CONFIG_FILE ${TEST_OFFER_NAME}_external_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/offer_tests/conf/${TEST_OFFER_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_SLAVE_CONFIG_FILE} - ${TEST_OFFER_SERVICE} - ) - - set(TEST_OFFER_MASTER_CONFIG_FILE ${TEST_OFFER_NAME}_external_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/offer_tests/conf/${TEST_OFFER_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_MASTER_CONFIG_FILE} - ${TEST_OFFER_SERVICE} - ) - - # generate and copy json files into builddir for big SD message test - set(TEST_OFFER_BIG_SLAVE_CONFIG_FILE ${TEST_OFFER_BIG_NAME}_slave.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/offer_tests/conf/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} - ${TEST_OFFER_BIG_SERVICE} - ) - - set(TEST_OFFER_BIG_MASTER_CONFIG_FILE ${TEST_OFFER_BIG_NAME}_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/offer_tests/conf/${TEST_OFFER_BIG_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} - ${TEST_OFFER_BIG_SERVICE} - ) - - # Copy starter scripts for external test to $BUILDDIR/test - set(TEST_OFFER_EXTERNAL_MASTER_STARTER ${TEST_OFFER_NAME}_external_master_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/offer_tests/conf/${TEST_OFFER_EXTERNAL_MASTER_STARTER}.in - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_EXTERNAL_MASTER_STARTER} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_EXTERNAL_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_EXTERNAL_MASTER_STARTER} - ${TEST_OFFER_SERVICE} - ) - set(TEST_OFFER_EXTERNAL_SLAVE_STARTER ${TEST_OFFER_NAME}_external_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_EXTERNAL_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_EXTERNAL_SLAVE_STARTER} - ${TEST_OFFER_SERVICE} - ) - set(TEST_OFFER_EXTERNAL_SLAVE_SD_STARTER ${TEST_OFFER_NAME}_external_slave_sd_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_EXTERNAL_SLAVE_SD_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_EXTERNAL_SLAVE_SD_STARTER} - ${TEST_OFFER_SERVICE} - ) - # Copy starter scripts for external test to $BUILDDIR/test - set(TEST_OFFER_BIG_MASTER_STARTER ${TEST_OFFER_BIG_NAME}_master_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/offer_tests/conf/${TEST_OFFER_BIG_MASTER_STARTER}.in - ${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_MASTER_STARTER} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_BIG_MASTER_STARTER} - ${TEST_OFFER_BIG_SERVICE} - ) - # Copy starter scripts for external test to $BUILDDIR/test - set(TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER ${TEST_OFFER_BIG_NAME}_slave_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offer_tests/${TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER} - ${TEST_OFFER_BIG_SERVICE} - ) -endif() - -############################################################################## -# offered services info tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_OFFERED_SERVICES_INFO_NAME offered_services_info_test) - set(TEST_OFFERED_SERVICES_INFO_SERVICE ${TEST_OFFERED_SERVICES_INFO_NAME}_service) - add_executable(${TEST_OFFERED_SERVICES_INFO_SERVICE} offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_NAME}_service.cpp) - target_link_libraries(${TEST_OFFERED_SERVICES_INFO_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_OFFERED_SERVICES_INFO_CLIENT ${TEST_OFFERED_SERVICES_INFO_NAME}_client) - add_executable(${TEST_OFFERED_SERVICES_INFO_CLIENT} offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_NAME}_client.cpp) - target_link_libraries(${TEST_OFFERED_SERVICES_INFO_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # copy starter scripts into builddir - set(TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER ${TEST_OFFERED_SERVICES_INFO_NAME}_local_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER} - ${TEST_OFFERED_SERVICES_INFO_SERVICE} - ) - - # Copy config file for local test into $BUILDDIR/test - set(TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE ${TEST_OFFERED_SERVICES_INFO_NAME}_local.json) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE} - ${TEST_OFFERED_SERVICES_INFO_SERVICE} - ) -endif() - -############################################################################## -# pending subscription tests tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_PENDING_SUBSCRIPTION_NAME pending_subscription_test) - set(TEST_PENDING_SUBSCRIPTION_SERVICE ${TEST_PENDING_SUBSCRIPTION_NAME}_service) - add_executable(${TEST_PENDING_SUBSCRIPTION_SERVICE} pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_NAME}_service.cpp) - target_link_libraries(${TEST_PENDING_SUBSCRIPTION_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - file(GLOB sd_sources - "../implementation/service_discovery/src/*entry*.cpp" - "../implementation/service_discovery/src/*option*.cpp" - "../implementation/service_discovery/src/*message*.cpp" - ) - set(TEST_PENDING_SUBSCRIPTION_CLIENT ${TEST_PENDING_SUBSCRIPTION_NAME}_sd_msg_sender) - add_executable(${TEST_PENDING_SUBSCRIPTION_CLIENT} - pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_NAME}_sd_msg_sender.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp - ${sd_sources} - ) - - target_link_libraries(${TEST_PENDING_SUBSCRIPTION_CLIENT} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - vsomeip3 - vsomeip3-sd - ) - - # copy starter scripts into builddir - set(TEST_PENDING_SUBSCRIPTION_MASTER_STARTER ${TEST_PENDING_SUBSCRIPTION_NAME}_master_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/pending_subscription_tests/conf/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER}.in - ${PROJECT_SOURCE_DIR}/test/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} - ${TEST_PENDING_SUBSCRIPTION_SERVICE} - ) - - # Copy config file for local test into $BUILDDIR/test - set(TEST_PENDING_SUBSCRIPTION_CONFIG_FILE ${TEST_PENDING_SUBSCRIPTION_NAME}_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/pending_subscription_tests/conf/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} - ${TEST_PENDING_SUBSCRIPTION_SERVICE} - ) -endif() - -############################################################################## -# malicious data tests -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_MALICIOUS_DATA_NAME malicious_data_test) - set(TEST_MALICIOUS_DATA_SERVICE ${TEST_MALICIOUS_DATA_NAME}_service) - add_executable(${TEST_MALICIOUS_DATA_SERVICE} malicious_data_tests/${TEST_MALICIOUS_DATA_NAME}_service.cpp) - target_link_libraries(${TEST_MALICIOUS_DATA_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - file(GLOB sd_sources - "../implementation/service_discovery/src/*entry*.cpp" - "../implementation/service_discovery/src/*option*.cpp" - "../implementation/service_discovery/src/*message*.cpp" - ) - set(TEST_MALICIOUS_DATA_CLIENT ${TEST_MALICIOUS_DATA_NAME}_msg_sender) - add_executable(${TEST_MALICIOUS_DATA_CLIENT} - malicious_data_tests/${TEST_MALICIOUS_DATA_CLIENT}.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp - ${sd_sources} - ) - - target_link_libraries(${TEST_MALICIOUS_DATA_CLIENT} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - vsomeip3 - vsomeip3-sd - ) - - # copy starter scripts into builddir - set(TEST_MALICIOUS_DATA_MASTER_STARTER ${TEST_MALICIOUS_DATA_NAME}_master_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/malicious_data_tests/conf/${TEST_MALICIOUS_DATA_MASTER_STARTER}.in - ${PROJECT_SOURCE_DIR}/test/malicious_data_tests/${TEST_MALICIOUS_DATA_MASTER_STARTER} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/malicious_data_tests/${TEST_MALICIOUS_DATA_MASTER_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_MASTER_STARTER} - ${TEST_MALICIOUS_DATA_SERVICE} - ) - - # Copy config file for local test into $BUILDDIR/test - set(TEST_MALICIOUS_DATA_CONFIG_FILE ${TEST_MALICIOUS_DATA_NAME}_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/malicious_data_tests/conf/${TEST_MALICIOUS_DATA_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/malicious_data_tests/${TEST_MALICIOUS_DATA_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/malicious_data_tests/${TEST_MALICIOUS_DATA_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_CONFIG_FILE} - ${TEST_MALICIOUS_DATA_SERVICE} - ) -endif() - -############################################################################## -# e2e test -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_E2E_NAME e2e_test) - set(TEST_E2E_SERVICE e2e_test_service) - set(TEST_E2E_CLIENT e2e_test_client) - - add_executable(${TEST_E2E_SERVICE} e2e_tests/${TEST_E2E_SERVICE}.cpp) - target_link_libraries(${TEST_E2E_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - add_executable(${TEST_E2E_CLIENT} - e2e_tests/${TEST_E2E_CLIENT}.cpp - ) - target_link_libraries(${TEST_E2E_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_E2E_NAME}_service_external.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/conf/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL}.in - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_SERVICE} - ) - - # Copy client config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_E2E_NAME}_client_external.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/conf/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL}.in - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_SERVICE} - ) - - # Copy bashscript to start external tests (master) into $BUILDDIR/test - set(TEST_E2E_EXTERNAL_MASTER_START_SCRIPT ${TEST_E2E_NAME}_external_master_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} - ${TEST_E2E_SERVICE} - ) - - # Copy bashscript to start external tests (slave) into $BUILDDIR/test - set(TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT ${TEST_E2E_NAME}_external_slave_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT} - ${TEST_E2E_SERVICE} - ) -endif() - -############################################################################## -# e2e profile 04 test -############################################################################## - -if(NOT ${TESTS_BAT} AND ${TEST_E2E_PROFILE_04}) - set(TEST_E2E_PROFILE_04_NAME e2e_profile_04_test) - set(TEST_E2E_PROFILE_04_SERVICE e2e_profile_04_test_service) - set(TEST_E2E_PROFILE_04_CLIENT e2e_profile_04_test_client) - - add_executable(${TEST_E2E_PROFILE_04_SERVICE} e2e_tests/${TEST_E2E_PROFILE_04_SERVICE}.cpp) - target_link_libraries(${TEST_E2E_PROFILE_04_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - add_executable(${TEST_E2E_PROFILE_04_CLIENT} - e2e_tests/${TEST_E2E_PROFILE_04_CLIENT}.cpp - ) - target_link_libraries(${TEST_E2E_PROFILE_04_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_E2E_PROFILE_04_NAME}_service_external.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/conf/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL}.in - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_PROFILE_04_SERVICE} - ) - - # Copy client config file for external allow tests into $BUILDDIR/test - set(TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_E2E_PROFILE_04_NAME}_client_external.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/conf/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL}.in - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} - ${TEST_E2E_PROFILE_04_SERVICE} - ) - - # Copy bashscript to start external tests (master) into $BUILDDIR/test - set(TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT ${TEST_E2E_PROFILE_04_NAME}_external_master_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} - ${TEST_E2E_PROFILE_04_SERVICE} - ) - - # Copy bashscript to start external tests (slave) into $BUILDDIR/test - set(TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT ${TEST_E2E_PROFILE_04_NAME}_external_slave_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/e2e_tests/${TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT} - ${TEST_E2E_PROFILE_04_SERVICE} - ) -endif() - -############################################################################## -# event tests -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_EVENT_NAME event_test) - set(TEST_EVENT_SERVICE ${TEST_EVENT_NAME}_service) - set(TEST_EVENT_CLIENT ${TEST_EVENT_NAME}_client) - - add_executable(${TEST_EVENT_SERVICE} event_tests/${TEST_EVENT_SERVICE}.cpp) - target_link_libraries(${TEST_EVENT_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - add_executable(${TEST_EVENT_CLIENT} - event_tests/${TEST_EVENT_CLIENT}.cpp - ) - target_link_libraries(${TEST_EVENT_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_EVENT_SLAVE_TCP_CONFIG_FILE ${TEST_EVENT_NAME}_slave_tcp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/event_tests/conf/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} - ${TEST_EVENT_SERVICE} - ) - - set(TEST_EVENT_SLAVE_UDP_CONFIG_FILE ${TEST_EVENT_NAME}_slave_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/event_tests/conf/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} - ${TEST_EVENT_SERVICE} - ) - - set(TEST_EVENT_MASTER_CONFIG_FILE ${TEST_EVENT_NAME}_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/event_tests/conf/${TEST_EVENT_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_MASTER_CONFIG_FILE} - ${TEST_EVENT_CLIENT} - ) - - # Copy bashscript to start test (master) into $BUILDDIR/test - set(TEST_EVENT_MASTER_START_SCRIPT ${TEST_EVENT_NAME}_master_starter.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_MASTER_START_SCRIPT} - ${TEST_EVENT_SERVICE} - ) - - # Copy bashscript to start external tests (slave) into $BUILDDIR/test - set(TEST_EVENT_SLAVE_START_SCRIPT ${TEST_EVENT_NAME}_slave_starter.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/event_tests/${TEST_EVENT_SLAVE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_SLAVE_START_SCRIPT} - ${TEST_EVENT_CLIENT} - ) - -endif() - -############################################################################## -# npdu-test -############################################################################## -if(NOT ${TESTS_BAT}) - set(TEST_NPDU_NAME npdu_test) - - set(TEST_NPDU_DAEMON npdu_test_rmd) - set(TEST_NPDU_DAEMON_CLIENT ${TEST_NPDU_DAEMON}_client_side) - add_executable(${TEST_NPDU_DAEMON_CLIENT} npdu_tests/${TEST_NPDU_DAEMON}.cpp) - set_target_properties(${TEST_NPDU_DAEMON_CLIENT} PROPERTIES COMPILE_FLAGS -DRMD_CLIENT_SIDE) - target_link_libraries(${TEST_NPDU_DAEMON_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_DAEMON_SERVICE ${TEST_NPDU_DAEMON}_service_side) - add_executable(${TEST_NPDU_DAEMON_SERVICE} npdu_tests/${TEST_NPDU_DAEMON}.cpp) - set_target_properties(${TEST_NPDU_DAEMON_SERVICE} PROPERTIES COMPILE_FLAGS -DRMD_SERVICE_SIDE) - target_link_libraries(${TEST_NPDU_DAEMON_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - ############################################################################## - - set(TEST_NPDU_SERVICE npdu_test_service) - - set(TEST_NPDU_SERVICE_ONE npdu_test_service_1) - add_executable(${TEST_NPDU_SERVICE_ONE} npdu_tests/${TEST_NPDU_SERVICE}.cpp) - set_target_properties(${TEST_NPDU_SERVICE_ONE} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=0) - target_link_libraries(${TEST_NPDU_SERVICE_ONE} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_SERVICE_TWO npdu_test_service_2) - add_executable(${TEST_NPDU_SERVICE_TWO} npdu_tests/${TEST_NPDU_SERVICE}.cpp) - set_target_properties(${TEST_NPDU_SERVICE_TWO} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=1) - target_link_libraries(${TEST_NPDU_SERVICE_TWO} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_SERVICE_THREE npdu_test_service_3) - add_executable(${TEST_NPDU_SERVICE_THREE} npdu_tests/${TEST_NPDU_SERVICE}.cpp) - set_target_properties(${TEST_NPDU_SERVICE_THREE} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=2) - target_link_libraries(${TEST_NPDU_SERVICE_THREE} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_SERVICE_FOUR npdu_test_service_4) - add_executable(${TEST_NPDU_SERVICE_FOUR} npdu_tests/${TEST_NPDU_SERVICE}.cpp) - set_target_properties(${TEST_NPDU_SERVICE_FOUR} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=3) - target_link_libraries(${TEST_NPDU_SERVICE_FOUR} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config file for service w/o npdu into $BUILDDIR/test - set(TEST_NPDU_SERVICE_CONFIG_FILE ${TEST_NPDU_SERVICE}_no_npdu.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/conf/${TEST_NPDU_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_SERVICE_CONFIG_FILE} - ${TEST_NPDU_SERVICE_ONE} - ) - - # Copy bashscript to start service w/o npdu into $BUILDDIR/test - set(TEST_NPDU_SERVICE_START_SCRIPT ${TEST_NPDU_SERVICE}_no_npdu_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_SERVICE_START_SCRIPT} - ${TEST_NPDU_SERVICE_ONE} - ) - - # Copy config file for service with npdu into $BUILDDIR/test - set(TEST_NPDU_SERVICE_CONFIG_FILE ${TEST_NPDU_SERVICE}_npdu.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/conf/${TEST_NPDU_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_SERVICE_CONFIG_FILE} - ${TEST_NPDU_SERVICE_ONE} - ) - - # Copy bashscript to start service with npdu into $BUILDDIR/test - set(TEST_NPDU_SERVICE_START_SCRIPT ${TEST_NPDU_SERVICE}_npdu_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_SERVICE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_SERVICE_START_SCRIPT} - ${TEST_NPDU_SERVICE_ONE} - ) - - ############################################################################## - - set(TEST_NPDU_CLIENT npdu_test_client) - - set(TEST_NPDU_CLIENT_ONE npdu_test_client_1) - add_executable(${TEST_NPDU_CLIENT_ONE} npdu_tests/${TEST_NPDU_CLIENT}.cpp) - target_link_libraries(${TEST_NPDU_CLIENT_ONE} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_CLIENT_TWO npdu_test_client_2) - add_executable(${TEST_NPDU_CLIENT_TWO} npdu_tests/${TEST_NPDU_CLIENT}.cpp) - target_link_libraries(${TEST_NPDU_CLIENT_TWO} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_CLIENT_THREE npdu_test_client_3) - add_executable(${TEST_NPDU_CLIENT_THREE} npdu_tests/${TEST_NPDU_CLIENT}.cpp) - target_link_libraries(${TEST_NPDU_CLIENT_THREE} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_NPDU_CLIENT_FOUR npdu_test_client_4) - add_executable(${TEST_NPDU_CLIENT_FOUR} npdu_tests/${TEST_NPDU_CLIENT}.cpp) - target_link_libraries(${TEST_NPDU_CLIENT_FOUR} - vsomeip3 - vsomeip3-cfg - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - # Copy config files for client w/o npdu into $BUILDDIR/test - set(TEST_NPDU_CLIENT_CONFIG_FILE ${TEST_NPDU_CLIENT}_no_npdu.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/conf/${TEST_NPDU_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_CLIENT_CONFIG_FILE} - ${TEST_NPDU_CLIENT_ONE} - ) - - # Copy bashscript to start client w/o npdu into $BUILDDIR/test - set(TEST_NPDU_CLIENT_START_SCRIPT ${TEST_NPDU_CLIENT}_no_npdu_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_CLIENT_START_SCRIPT} - ${TEST_NPDU_CLIENT_ONE} - ) - - # Copy config file for client with npdu into $BUILDDIR/test - set(TEST_NPDU_CLIENT_CONFIG_FILE ${TEST_NPDU_CLIENT}_npdu.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/conf/${TEST_NPDU_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_CLIENT_CONFIG_FILE} - ${TEST_NPDU_CLIENT_ONE} - ) - - # Copy bashscript to start client with npdu into $BUILDDIR/test - set(TEST_NPDU_CLIENT_START_SCRIPT ${TEST_NPDU_CLIENT}_npdu_start.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_CLIENT_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_CLIENT_START_SCRIPT} - ${TEST_NPDU_CLIENT_ONE} - ) - - ############################################################################## - - set(TEST_NPDU_STARTER ${TEST_NPDU_NAME}_starter.sh) - copy_to_builddir(${PROJECT_SOURCE_DIR}/test/npdu_tests/${TEST_NPDU_STARTER} - ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_STARTER} - ${TEST_NPDU_DAEMON_CLIENT} - ) -endif() - -############################################################################## -# someip tp tests -############################################################################## - -if(NOT ${TESTS_BAT}) - set(TEST_SOMEIPTP_NAME someip_tp_test) - set(TEST_SOMEIPTP_SERVICE ${TEST_SOMEIPTP_NAME}_service) - - add_executable(${TEST_SOMEIPTP_SERVICE} someip_tp_tests/${TEST_SOMEIPTP_SERVICE}.cpp) - target_link_libraries(${TEST_SOMEIPTP_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - file(GLOB sd_sources - "../implementation/service_discovery/src/*entry*.cpp" - "../implementation/service_discovery/src/*option*.cpp" - "../implementation/service_discovery/src/*message*.cpp" - ) - set(TEST_SOMEIPTP_CLIENT ${TEST_SOMEIPTP_NAME}_msg_sender) - add_executable(${TEST_SOMEIPTP_CLIENT} - someip_tp_tests/${TEST_SOMEIPTP_CLIENT}.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp - ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp - ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp.cpp - ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp_reassembler.cpp - ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp_message.cpp - ${sd_sources} - ) - - target_link_libraries(${TEST_SOMEIPTP_CLIENT} - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - vsomeip3 - vsomeip3-sd - ) - - # Copy service config file for external allow tests into $BUILDDIR/test - set(TEST_SOMEIPTP_MASTER_CONFIG_FILE ${TEST_SOMEIPTP_NAME}_master.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/someip_tp_tests/conf/${TEST_SOMEIPTP_MASTER_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/someip_tp_tests/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/someip_tp_tests/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} - ${TEST_SOMEIPTP_CLIENT} - ) - - # Copy bashscript to start test (master) into $BUILDDIR/test - set(TEST_SOMEIPTP_MASTER_START_SCRIPT ${TEST_SOMEIPTP_NAME}_master_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/someip_tp_tests/conf/${TEST_SOMEIPTP_MASTER_START_SCRIPT}.in - ${PROJECT_SOURCE_DIR}/test/someip_tp_tests/${TEST_SOMEIPTP_MASTER_START_SCRIPT} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/someip_tp_tests/${TEST_SOMEIPTP_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} - ${TEST_SOMEIPTP_SERVICE} - ) -endif() - -############################################################################## -# second IP address tests -############################################################################## - -if(NOT ${TESTS_BAT} AND ${TEST_SECOND_ADDRESS}) - set(TEST_SECOND_ADDRESS_NAME second_address_test) - set(TEST_SECOND_ADDRESS_SERVICE ${TEST_SECOND_ADDRESS_NAME}_service) - set(TEST_SECOND_ADDRESS_CLIENT ${TEST_SECOND_ADDRESS_NAME}_client) - - add_executable(${TEST_SECOND_ADDRESS_SERVICE} - second_address_tests/${TEST_SECOND_ADDRESS_SERVICE}.cpp - ) - target_link_libraries(${TEST_SECOND_ADDRESS_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - add_executable(${TEST_SECOND_ADDRESS_CLIENT} - second_address_tests/${TEST_SECOND_ADDRESS_CLIENT}.cpp - ) - target_link_libraries(${TEST_SECOND_ADDRESS_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_master_service_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/conf/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} - ${TEST_SECOND_ADDRESS_SERVICE} - ) - - set(TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_slave_client.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} - ${TEST_SECOND_ADDRESS_CLIENT} - ) - - set(TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_master_client.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/conf/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} - ${TEST_SECOND_ADDRESS_CLIENT} - ) - - set(TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_slave_service_udp.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} - ${TEST_SECOND_ADDRESS_SERVICE} - ) - - set(TEST_SECOND_ADDRESS_MASTER_START_SCRIPT ${TEST_SECOND_ADDRESS_NAME}_master_starter.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} - ${TEST_SECOND_ADDRESS_SERVICE} - ) - - set(TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT ${TEST_SECOND_ADDRESS_NAME}_slave_starter.sh) - configure_file( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT}.in - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} - ${TEST_SECOND_ADDRESS_CLIENT} - ) -endif() - -############################################################################## -# suspend resume tests -############################################################################## -if(NOT ${TESTS_BAT}) - - set(TEST_SUSPEND_RESUME_NAME suspend_resume_test) - set(TEST_SUSPEND_RESUME_SERVICE ${TEST_SUSPEND_RESUME_NAME}_service) - set(TEST_SUSPEND_RESUME_CLIENT ${TEST_SUSPEND_RESUME_NAME}_client) - - add_executable(${TEST_SUSPEND_RESUME_SERVICE} - suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE}.cpp - ) - target_link_libraries(${TEST_SUSPEND_RESUME_SERVICE} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - add_executable(${TEST_SUSPEND_RESUME_CLIENT} - suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT}.cpp - ) - target_link_libraries(${TEST_SUSPEND_RESUME_CLIENT} - vsomeip3 - ${Boost_LIBRARIES} - ${DL_LIBRARY} - ${TEST_LINK_LIBRARIES} - ) - - set(TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE ${TEST_SUSPEND_RESUME_SERVICE}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/conf/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} - ${TEST_SUSPEND_RESUME_CLIENT} - ) - - set(TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE ${TEST_SUSPEND_RESUME_CLIENT}.json) - configure_file( - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/conf/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE}.in - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} - @ONLY) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} - ${PROJECT_BINARY_DIR}/test/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} - ${TEST_SUSPEND_RESUME_CLIENT} - ) - - set(TEST_SUSPEND_RESUME_MASTER_START_SCRIPT ${TEST_SUSPEND_RESUME_NAME}_master_starter.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} - ${TEST_SUSPEND_RESUME_CLIENT} - ) - - set(TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT ${TEST_SUSPEND_RESUME_NAME}_slave_starter.sh) - copy_to_builddir( - ${PROJECT_SOURCE_DIR}/test/suspend_resume_tests/${TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT} - ${PROJECT_BINARY_DIR}/test/${TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT} - ${TEST_SUSPEND_RESUME_CLIENT} - ) - -endif() - ############################################################################## -# Add for every test a dependency to gtest +# add network, unit and benchmark tests directories ############################################################################## +add_subdirectory( network_tests EXCLUDE_FROM_ALL ) -if(NOT ${TESTS_BAT}) - add_dependencies(${TEST_CONFIGURATION} gtest) - add_dependencies(${TEST_APPLICATION} gtest) - add_dependencies(${TEST_APPLICATION_SINGLE_PROCESS_NAME} gtest) - add_dependencies(${TEST_APPLICATION_AVAILABILITY_NAME} gtest) - add_dependencies(${TEST_MAGIC_COOKIES_CLIENT} gtest) - add_dependencies(${TEST_MAGIC_COOKIES_SERVICE} gtest) - add_dependencies(${TEST_HEADER_FACTORY} gtest) - add_dependencies(${TEST_HEADER_FACTORY_CLIENT} gtest) - add_dependencies(${TEST_HEADER_FACTORY_SERVICE} gtest) - add_dependencies(${TEST_LOCAL_ROUTING_SERVICE} gtest) - add_dependencies(${TEST_LOCAL_ROUTING_CLIENT} gtest) - add_dependencies(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} gtest) - add_dependencies(${TEST_PAYLOAD_SERVICE} gtest) - add_dependencies(${TEST_PAYLOAD_CLIENT} gtest) - add_dependencies(${TEST_BIG_PAYLOAD_SERVICE} gtest) - add_dependencies(${TEST_BIG_PAYLOAD_CLIENT} gtest) - add_dependencies(${TEST_CLIENT_ID_SERVICE} gtest) - add_dependencies(${TEST_CLIENT_ID_UTILITY} gtest) - add_dependencies(${TEST_SUBSCRIBE_NOTIFY_SERVICE} gtest) - add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} gtest) - add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} gtest) - add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} gtest) - add_dependencies(${TEST_CPU_LOAD_SERVICE} gtest) - add_dependencies(${TEST_CPU_LOAD_CLIENT} gtest) - add_dependencies(${TEST_INITIAL_EVENT_SERVICE} gtest) - add_dependencies(${TEST_INITIAL_EVENT_CLIENT} gtest) - add_dependencies(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} gtest) - add_dependencies(${TEST_INITIAL_EVENT_STOP_SERVICE} gtest) - add_dependencies(${TEST_OFFER_SERVICE} gtest) - add_dependencies(${TEST_OFFER_CLIENT} gtest) - add_dependencies(${TEST_OFFER_SERVICE_EXTERNAL} gtest) - add_dependencies(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} gtest) - add_dependencies(${TEST_OFFER_SERVICE_AVAILABILITY_CHECKER} gtest) - add_dependencies(${TEST_OFFERED_SERVICES_INFO_CLIENT} gtest) - add_dependencies(${TEST_OFFERED_SERVICES_INFO_SERVICE} gtest) - add_dependencies(${TEST_PENDING_SUBSCRIPTION_SERVICE} gtest) - add_dependencies(${TEST_PENDING_SUBSCRIPTION_CLIENT} gtest) - add_dependencies(${TEST_MALICIOUS_DATA_SERVICE} gtest) - add_dependencies(${TEST_MALICIOUS_DATA_CLIENT} gtest) - if (${TEST_SECURITY}) - add_dependencies(${TEST_SECURITY_SERVICE} gtest) - add_dependencies(${TEST_SECURITY_CLIENT} gtest) - endif() - add_dependencies(${TEST_E2E_SERVICE} gtest) - add_dependencies(${TEST_E2E_CLIENT} gtest) - if (${TEST_E2E_PROFILE_04}) - add_dependencies(${TEST_E2E_PROFILE_04_SERVICE} gtest) - add_dependencies(${TEST_E2E_PROFILE_04_CLIENT} gtest) - endif() - add_dependencies(${TEST_EVENT_SERVICE} gtest) - add_dependencies(${TEST_EVENT_CLIENT} gtest) - add_dependencies(${TEST_NPDU_SERVICE_ONE} gtest) - add_dependencies(${TEST_NPDU_SERVICE_TWO} gtest) - add_dependencies(${TEST_NPDU_SERVICE_THREE} gtest) - add_dependencies(${TEST_NPDU_SERVICE_FOUR} gtest) - add_dependencies(${TEST_NPDU_CLIENT_ONE} gtest) - add_dependencies(${TEST_NPDU_CLIENT_TWO} gtest) - add_dependencies(${TEST_NPDU_CLIENT_THREE} gtest) - add_dependencies(${TEST_NPDU_CLIENT_FOUR} gtest) - add_dependencies(${TEST_NPDU_DAEMON_CLIENT} gtest) - add_dependencies(${TEST_NPDU_DAEMON_SERVICE} gtest) - add_dependencies(${TEST_SOMEIPTP_CLIENT} gtest) - add_dependencies(${TEST_SOMEIPTP_SERVICE} gtest) - if(${TEST_SECOND_ADDRESS}) - add_dependencies(${TEST_SECOND_ADDRESS_CLIENT} gtest) - add_dependencies(${TEST_SECOND_ADDRESS_SERVICE} gtest) - endif() - add_dependencies(${TEST_SUSPEND_RESUME_CLIENT} gtest) - add_dependencies(${TEST_SUSPEND_RESUME_SERVICE} gtest) -else() - add_dependencies(${TEST_LOCAL_ROUTING_SERVICE} gtest) - add_dependencies(${TEST_LOCAL_ROUTING_CLIENT} gtest) -endif() - -############################################################################## -# Add tests to the target build_tests -############################################################################## +if (NOT DISABLE_SECURITY) + add_subdirectory( unit_tests EXCLUDE_FROM_ALL ) -if(NOT ${TESTS_BAT}) - add_dependencies(build_tests ${TEST_CONFIGURATION}) - add_dependencies(build_tests ${TEST_APPLICATION}) - add_dependencies(build_tests ${TEST_APPLICATION_SINGLE_PROCESS_NAME}) - add_dependencies(build_tests ${TEST_APPLICATION_AVAILABILITY_NAME}) - add_dependencies(build_tests ${TEST_MAGIC_COOKIES_CLIENT}) - add_dependencies(build_tests ${TEST_MAGIC_COOKIES_SERVICE}) - add_dependencies(build_tests ${TEST_HEADER_FACTORY}) - add_dependencies(build_tests ${TEST_HEADER_FACTORY_CLIENT}) - add_dependencies(build_tests ${TEST_HEADER_FACTORY_SERVICE}) - add_dependencies(build_tests ${TEST_LOCAL_ROUTING_SERVICE}) - add_dependencies(build_tests ${TEST_LOCAL_ROUTING_CLIENT}) - add_dependencies(build_tests ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}) - add_dependencies(build_tests ${TEST_PAYLOAD_SERVICE}) - add_dependencies(build_tests ${TEST_PAYLOAD_CLIENT}) - add_dependencies(build_tests ${TEST_BIG_PAYLOAD_SERVICE}) - add_dependencies(build_tests ${TEST_BIG_PAYLOAD_CLIENT}) - add_dependencies(build_tests ${TEST_CLIENT_ID_SERVICE}) - add_dependencies(build_tests ${TEST_CLIENT_ID_UTILITY}) - add_dependencies(build_tests ${TEST_SUBSCRIBE_NOTIFY_SERVICE}) - add_dependencies(build_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE}) - add_dependencies(build_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT}) - add_dependencies(build_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE}) - add_dependencies(build_tests ${TEST_CPU_LOAD_SERVICE}) - add_dependencies(build_tests ${TEST_CPU_LOAD_CLIENT}) - add_dependencies(build_tests ${TEST_INITIAL_EVENT_SERVICE}) - add_dependencies(build_tests ${TEST_INITIAL_EVENT_CLIENT}) - add_dependencies(build_tests ${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER}) - add_dependencies(build_tests ${TEST_INITIAL_EVENT_STOP_SERVICE}) - add_dependencies(build_tests ${TEST_OFFER_SERVICE}) - add_dependencies(build_tests ${TEST_OFFER_CLIENT}) - add_dependencies(build_tests ${TEST_OFFER_SERVICE_EXTERNAL}) - add_dependencies(build_tests ${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER}) - add_dependencies(build_tests ${TEST_OFFER_SERVICE_AVAILABILITY_CHECKER}) - add_dependencies(build_tests ${TEST_OFFER_BIG_SERVICE}) - add_dependencies(build_tests ${TEST_OFFER_BIG_CLIENT}) - add_dependencies(build_tests ${TEST_RESTART_ROUTING_SERVICE}) - add_dependencies(build_tests ${TEST_RESTART_ROUTING_CLIENT}) - if (${TEST_SECURITY}) - add_dependencies(build_tests ${TEST_SECURITY_SERVICE}) - add_dependencies(build_tests ${TEST_SECURITY_CLIENT}) + if(benchmark_FOUND) + add_subdirectory( benchmark_tests EXCLUDE_FROM_ALL ) endif() - add_dependencies(build_tests ${TEST_OFFERED_SERVICES_INFO_CLIENT}) - add_dependencies(build_tests ${TEST_OFFERED_SERVICES_INFO_SERVICE}) - add_dependencies(build_tests ${TEST_PENDING_SUBSCRIPTION_SERVICE}) - add_dependencies(build_tests ${TEST_PENDING_SUBSCRIPTION_CLIENT}) - add_dependencies(build_tests ${TEST_MALICIOUS_DATA_SERVICE}) - add_dependencies(build_tests ${TEST_MALICIOUS_DATA_CLIENT}) - add_dependencies(build_tests ${TEST_E2E_SERVICE}) - add_dependencies(build_tests ${TEST_E2E_CLIENT}) - if (${TEST_E2E_PROFILE_04}) - add_dependencies(build_tests ${TEST_E2E_PROFILE_04_SERVICE}) - add_dependencies(build_tests ${TEST_E2E_PROFILE_04_CLIENT}) - endif() - add_dependencies(build_tests ${TEST_EVENT_SERVICE}) - add_dependencies(build_tests ${TEST_EVENT_CLIENT}) - add_dependencies(build_tests ${TEST_NPDU_SERVICE_ONE}) - add_dependencies(build_tests ${TEST_NPDU_SERVICE_TWO}) - add_dependencies(build_tests ${TEST_NPDU_SERVICE_THREE}) - add_dependencies(build_tests ${TEST_NPDU_SERVICE_FOUR}) - add_dependencies(build_tests ${TEST_NPDU_CLIENT_ONE}) - add_dependencies(build_tests ${TEST_NPDU_CLIENT_TWO}) - add_dependencies(build_tests ${TEST_NPDU_CLIENT_THREE}) - add_dependencies(build_tests ${TEST_NPDU_CLIENT_FOUR}) - add_dependencies(build_tests ${TEST_NPDU_DAEMON_CLIENT}) - add_dependencies(build_tests ${TEST_NPDU_DAEMON_SERVICE}) - add_dependencies(build_tests ${TEST_SOMEIPTP_CLIENT}) - add_dependencies(build_tests ${TEST_SOMEIPTP_SERVICE}) - if(${TEST_SECOND_ADDRESS}) - add_dependencies(build_tests ${TEST_SECOND_ADDRESS_CLIENT}) - add_dependencies(build_tests ${TEST_SECOND_ADDRESS_SERVICE}) - endif() - add_dependencies(build_tests ${TEST_SUSPEND_RESUME_CLIENT}) - add_dependencies(build_tests ${TEST_SUSPEND_RESUME_SERVICE}) -else() - add_dependencies(build_tests ${TEST_LOCAL_ROUTING_SERVICE}) - add_dependencies(build_tests ${TEST_LOCAL_ROUTING_CLIENT}) endif() -# some tests require the routingmanagerd -add_dependencies(build_tests routingmanagerd) - ############################################################################## -# Add tests +# Add internal_routing_disabled_acceptance_test ############################################################################## if(NOT ${TESTS_BAT}) - add_test(NAME ${TEST_CONFIGURATION} - COMMAND ${TEST_CONFIGURATION} - ) - - # application test - add_test(NAME ${TEST_APPLICATION} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_STARTER} - ) - set_tests_properties(${TEST_APPLICATION} PROPERTIES TIMEOUT 80) - add_test(NAME ${TEST_APPLICATION_SINGLE_PROCESS_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} - ) - set_tests_properties(${TEST_APPLICATION_SINGLE_PROCESS_NAME} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_APPLICATION_AVAILABILITY_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_APPLICATION_AVAILABILITY_STARTER} - ) - set_tests_properties(${TEST_APPLICATION_AVAILABILITY_NAME} PROPERTIES TIMEOUT 120) - - # magic cookies test - add_test(NAME ${TEST_MAGIC_COOKIES_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_MAGIC_COOKIES_STARTER} - ) - set_tests_properties(${TEST_MAGIC_COOKIES_NAME} PROPERTIES TIMEOUT 250) - - # Header/Factory tets - add_test(NAME ${TEST_HEADER_FACTORY_NAME} COMMAND ${TEST_HEADER_FACTORY}) - add_test(NAME ${TEST_HEADER_FACTORY_NAME}_send_receive - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_HEADER_FACTORY_STARTER} - ) - - # Routing tests - add_test(NAME ${TEST_LOCAL_ROUTING_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_STARTER} - ) - - add_test(NAME ${TEST_EXTERNAL_LOCAL_ROUTING_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} - ) - set_tests_properties(${TEST_EXTERNAL_LOCAL_ROUTING_NAME} PROPERTIES TIMEOUT 120) - - # Payload tests - add_test(NAME ${TEST_LOCAL_PAYLOAD_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_STARTER} - ) - add_test(NAME ${TEST_LOCAL_PAYLOAD_HUGE_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} - ) - set_tests_properties(${TEST_LOCAL_PAYLOAD_HUGE_NAME} PROPERTIES TIMEOUT 960) - add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} - ) - add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} - ) - set_tests_properties(${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} PROPERTIES TIMEOUT 480) - add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} - ) - set_tests_properties(${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} PROPERTIES TIMEOUT 480) - - # big payload tests - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER} - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER} RANDOM - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER} LIMITED - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} RANDOM - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} LIMITED - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} LIMITEDGENERAL - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL - ) - set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDSPECIFIC - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} UDP - ) - set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP} PROPERTIES TIMEOUT 120) - - # client id tests - add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY} - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY} PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_511 - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_511 - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_511 PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_4095 - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_4095 - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_4095 PROPERTIES TIMEOUT 600) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_127 - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_127 - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_127 PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CLIENT_ID_UTILITY}) - set_property(TEST ${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 - APPEND PROPERTY ENVIRONMENT - "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE}") - set_tests_properties(${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 PROPERTIES TIMEOUT 120) - - # subscribe notify tests - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} SAME_SERVICE_ID) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp PROPERTIES TIMEOUT 120) - - # subscribe notify one id tests - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) - set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - # cpu load tests - add_test(NAME ${TEST_CPU_LOAD_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_CPU_LOAD_MASTER_STARTER} - ) - set_tests_properties(${TEST_CPU_LOAD_NAME} PROPERTIES TIMEOUT 3000) - - # initial event tests - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_partial_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_same_service_id_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID MULTIPLE_EVENTS) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_partial_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_same_service_id_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_tcp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_both_tcp_and_udp PROPERTIES TIMEOUT 120) - - add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp_client_subscribes_twice - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP CLIENT_SUBSCRIBES_TWICE) - set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp_client_subscribes_twice PROPERTIES TIMEOUT 120) - - # offer tests - add_test(NAME ${TEST_OFFER_NAME}_local - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_LOCAL_STARTER}) - set_tests_properties(${TEST_OFFER_NAME}_local PROPERTIES TIMEOUT 180) - add_test(NAME ${TEST_OFFER_NAME}_external - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_EXTERNAL_MASTER_STARTER}) - set_tests_properties(${TEST_OFFER_NAME}_local PROPERTIES TIMEOUT 360) - add_test(NAME ${TEST_OFFER_BIG_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_BIG_MASTER_STARTER}) - set_tests_properties(${TEST_OFFER_BIG_NAME} PROPERTIES TIMEOUT 360) - - # offered services info tets - add_test(NAME ${TEST_OFFERED_SERVICES_INFO_NAME}_local - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER}) - set_tests_properties(${TEST_OFFERED_SERVICES_INFO_NAME}_local PROPERTIES TIMEOUT 180) - - # Restart-Routing tests - add_test(NAME ${TEST_RESTART_ROUTING_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_STARTER} - ) - if (${TEST_SECURITY}) - # Security tests - add_test(NAME ${TEST_SECURITY_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} - ) - add_test(NAME ${TEST_SECURITY_NAME}_external_allow - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} security_test_config_client_external_allow.json --allow - ) - add_test(NAME ${TEST_SECURITY_NAME}_external_deny - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} security_test_config_client_external_deny.json --deny - ) - endif() - - # pending subscriptions test - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_unsubscribe - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} UNSUBSCRIBE) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_unsubscribe PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_nack - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE_NACK) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_nack PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_same_port - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE_SAME_PORT) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_same_port PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_resubscribe_mixed - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_RESUBSCRIBE_MIXED) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_resubscribe_mixed PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_stopsubscribe_subscribe - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_stopsubscribe_subscribe PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_send_request_to_sd_port - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} REQUEST_TO_SD) - set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_send_request_to_sd_port PROPERTIES TIMEOUT 180) - - # malicious data test - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_events - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_MASTER_STARTER} MALICIOUS_EVENTS) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_events PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_protocol_version - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_MASTER_STARTER} PROTOCOL_VERSION) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_protocol_version PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_message_type - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_MASTER_STARTER} MESSAGE_TYPE) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_message_type PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_return_code - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_MASTER_STARTER} RETURN_CODE) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_return_code PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_wrong_header_fields_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_MALICIOUS_DATA_MASTER_STARTER} WRONG_HEADER_FIELDS_UDP) - set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_wrong_header_fields_udp PROPERTIES TIMEOUT 180) - - # npdu tests - add_test(NAME ${TEST_NPDU_NAME}_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_STARTER} UDP sync) - set_tests_properties(${TEST_NPDU_NAME}_udp PROPERTIES TIMEOUT 840) - - add_test(NAME ${TEST_NPDU_NAME}_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_NPDU_STARTER} TCP sync) - set_tests_properties(${TEST_NPDU_NAME}_tcp PROPERTIES TIMEOUT 840) - - # e2e tests - add_test(NAME ${TEST_E2E_NAME}_external - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} e2e_test_client_external.json) - set_tests_properties(${TEST_E2E_NAME}_external PROPERTIES TIMEOUT 180) - - if (${TEST_E2E_PROFILE_04}) - add_test(NAME ${TEST_E2E_PROFILE_04_NAME}_external - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} e2e_profile_04_test_client_external.json) - set_tests_properties(${TEST_E2E_PROFILE_04_NAME}_external PROPERTIES TIMEOUT 180) - endif () - - # event tests - add_test(NAME ${TEST_EVENT_NAME}_payload_fixed_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_FIXED UDP) - set_tests_properties(${TEST_EVENT_NAME}_payload_fixed_udp PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_EVENT_NAME}_payload_fixed_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_FIXED TCP) - set_tests_properties(${TEST_EVENT_NAME}_payload_fixed_tcp PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_EVENT_NAME}_payload_dynamic_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_DYNAMIC UDP) - set_tests_properties(${TEST_EVENT_NAME}_payload_dynamic_udp PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_EVENT_NAME}_payload_dynamic_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_DYNAMIC TCP) - set_tests_properties(${TEST_EVENT_NAME}_payload_dynamic_tcp PROPERTIES TIMEOUT 180) - - # SOME/IP-TP tests - add_test(NAME ${TEST_SOMEIPTP_NAME}_in_sequence - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} IN_SEQUENCE) - set_tests_properties(${TEST_SOMEIPTP_NAME}_in_sequence PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_mixed - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} MIXED) - set_tests_properties(${TEST_SOMEIPTP_NAME}_mixed PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_incomplete - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} INCOMPLETE) - set_tests_properties(${TEST_SOMEIPTP_NAME}_incomplete PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_duplicate - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} DUPLICATE) - set_tests_properties(${TEST_SOMEIPTP_NAME}_duplicate PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_overlap - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} OVERLAP) - set_tests_properties(${TEST_SOMEIPTP_NAME}_overlap PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SOMEIPTP_NAME}_overlap_front_back - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SOMEIPTP_MASTER_START_SCRIPT} OVERLAP_FRONT_BACK) - set_tests_properties(${TEST_SOMEIPTP_NAME}_overlap_front_back PROPERTIES TIMEOUT 180) - - if(${TEST_SECOND_ADDRESS}) - add_test(NAME ${TEST_SECOND_ADDRESS_NAME}_second_ip_address_service_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} SERVICE UDP - ) - set_tests_properties(${TEST_SECOND_ADDRESS_NAME}_second_ip_address_service_udp PROPERTIES TIMEOUT 180) - - add_test(NAME ${TEST_SECOND_ADDRESS_NAME}_second_ip_address_client_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} CLIENT UDP - ) - set_tests_properties(${TEST_SECOND_ADDRESS_NAME}_second_ip_address_client_udp PROPERTIES TIMEOUT 180) - endif() - - # suspend resume test - add_test(NAME ${TEST_SUSPEND_RESUME_NAME}_initial - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} SERVICE - ) - set_tests_properties(${TEST_SUSPEND_RESUME_NAME}_initial PROPERTIES TIMEOUT 80) - -else() - # Routing tests - add_test(NAME ${TEST_LOCAL_ROUTING_NAME} - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_LOCAL_ROUTING_STARTER} - ) + add_subdirectory(internal_routing_disabled_acceptance_test) endif() diff --git a/test/application_tests/application_test.cpp b/test/application_tests/application_test.cpp deleted file mode 100644 index e39cf1f..0000000 --- a/test/application_tests/application_test.cpp +++ /dev/null @@ -1,479 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include - -#include - -#include - -#include "someip_test_globals.hpp" - -using namespace vsomeip; - -class someip_application_test: public ::testing::Test { -public: - someip_application_test() : - registered_(false) { - - } -protected: - void SetUp() { - app_ = runtime::get()->create_application("application_test"); - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - - app_->register_state_handler( - std::bind(&someip_application_test::on_state, this, - std::placeholders::_1)); - } - - void on_state(vsomeip::state_type_e _state) { - registered_ = (_state == vsomeip::state_type_e::ST_REGISTERED); - } - - bool registered_; - std::shared_ptr app_; -}; - -/** - * @test Start and stop application - */ -TEST_F(someip_application_test, start_stop_application) -{ - std::promise its_promise; - std::thread t([&](){ - its_promise.set_value(true); - app_->start(); - }); - EXPECT_TRUE(its_promise.get_future().get()); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - app_->stop(); - t.join(); -} - -/** - * @test Start and stop application multiple times - */ -TEST_F(someip_application_test, start_stop_application_multiple) -{ - for (int i = 0; i < 10; ++i) { - std::promise its_promise; - std::thread t([&]() { - its_promise.set_value(true); - app_->start(); - }); - EXPECT_TRUE(its_promise.get_future().get()); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - app_->stop(); - t.join(); - } -} - -/** - * @test Start and stop application multiple times and offer a service - */ -TEST_F(someip_application_test, start_stop_application_multiple_offer_service) -{ - for (int i = 0; i < 10; ++i) { - std::promise its_promise; - std::thread t([&]() { - its_promise.set_value(true); - app_->start(); - }); - EXPECT_TRUE(its_promise.get_future().get()); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - app_->stop(); - t.join(); - } -} - -/** - * @test Try to start an already running application again - */ -TEST_F(someip_application_test, restart_without_stopping) -{ - std::promise its_promise; - std::thread t([&]() { - its_promise.set_value(true); - app_->start(); - - }); - EXPECT_TRUE(its_promise.get_future().get()); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - VSOMEIP_WARNING << "An error message should appear now"; - // should print error - app_->start(); - app_->stop(); - t.join(); -} - -/** - * @test Try to stop a running application twice - */ -TEST_F(someip_application_test, stop_application_twice) -{ - std::promise its_promise; - std::thread t([&]() { - its_promise.set_value(true); - app_->start(); - - }); - EXPECT_TRUE(its_promise.get_future().get()); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - app_->stop(); - t.join(); - app_->stop(); -} - -/** - * @test Checks whether watchdog handler is invoked (regularly) also after restarting. - */ -TEST_F(someip_application_test, watchdog_handler) -{ - std::atomic cb_count(0); - auto wd_handler = [&] () { - ++cb_count; - }; - - app_->set_watchdog_handler(std::cref(wd_handler), std::chrono::seconds(1)); - - std::promise its_promise; - std::thread t([&]() { - its_promise.set_value(true); - app_->start(); - }); - EXPECT_TRUE(its_promise.get_future().get()); - - // wait till watchdog handler has been invoked once - while (0 == cb_count.load()) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - ASSERT_EQ(1, cb_count.load()); - - // clear handler (must not be called again) - app_->set_watchdog_handler(nullptr, std::chrono::seconds::zero()); - - // wait doubled interval (used previously).. - std::this_thread::sleep_for(std::chrono::seconds(2)); - // .. to ensure it was not called again - ASSERT_EQ(1, cb_count.load()); - - // enable handler again - app_->set_watchdog_handler(std::cref(wd_handler), std::chrono::seconds(1)); - - // wait till watchdog handler has been invoked again (2nd time) - while (1 == cb_count.load()) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - - app_->stop(); - t.join(); - - // wait doubled interval (used previously).. - std::this_thread::sleep_for(std::chrono::seconds(2)); - // .. to ensure it was not called after stop() - ASSERT_EQ(2, cb_count.load()); - - // restart application (w/ watchdog handler still set) - std::promise its_promise2; - std::thread t2([&]() { - its_promise2.set_value(true); - app_->start(); - }); - EXPECT_TRUE(its_promise2.get_future().get()); - - // wait till watchdog handler has been invoked again (3rd time) - while (2 == cb_count.load()) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - ASSERT_EQ(3, cb_count.load()); - - // clear handler again (must not be called again), this time via zero interval - app_->set_watchdog_handler(std::cref(wd_handler), std::chrono::seconds::zero()); - - // wait doubled interval (used previously).. - std::this_thread::sleep_for(std::chrono::seconds(2)); - // .. to ensure it was not called again - ASSERT_EQ(3, cb_count.load()); - - app_->stop(); - t2.join(); -} - -class someip_application_shutdown_test: public ::testing::Test { - -protected: - void SetUp() { - is_registered_ = false; - is_available_ = false; - - app_ = runtime::get()->create_application("application_test"); - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, - std::bind(&someip_application_shutdown_test::on_message_shutdown, this, - std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&someip_application_shutdown_test::on_state, this, - std::placeholders::_1)); - app_->register_availability_handler( - vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - std::bind(&someip_application_shutdown_test::on_availability, - this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - - shutdown_thread_ = std::thread(&someip_application_shutdown_test::send_shutdown_message, this); - - app_->start(); - } - - void TearDown() { - shutdown_thread_.join(); - app_->stop(); - app_.reset(); - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - } - - void on_state(vsomeip::state_type_e _state) { - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - std::lock_guard its_lock(mutex_); - is_registered_ = true; - cv_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - (void)_service; - (void)_instance; - if(_is_available) { - std::lock_guard its_lock(mutex_); - is_available_ = _is_available; - cv_.notify_one(); - } - } - - void on_message_shutdown(const std::shared_ptr& _request) - { - (void)_request; - VSOMEIP_INFO << "Shutdown method was called, going down now."; - app_->clear_all_handler(); - app_->stop(); - } - - void send_shutdown_message() { - { - std::unique_lock its_lock(mutex_); - while (!is_registered_) { - if (std::cv_status::timeout - == cv_.wait_for(its_lock, std::chrono::seconds(10))) { - ADD_FAILURE()<< "Application wasn't registered in time!"; - is_registered_ = true; - } - } - app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID); - app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID); - while (!is_available_) { - if (std::cv_status::timeout - == cv_.wait_for(its_lock, std::chrono::seconds(10))) { - ADD_FAILURE()<< "Service didn't become available in time!"; - is_available_ = true; - } - } - } - - std::shared_ptr r = runtime::get()->create_request(); - r->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - r->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - r->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); - app_->send(r); - } - - bool is_registered_; - bool is_available_; - std::shared_ptr app_; - std::condition_variable cv_; - std::mutex mutex_; - std::thread shutdown_thread_; -}; - -class someip_application_exception_test: public ::testing::Test { - -protected: - void SetUp() { - is_registered_ = false; - is_available_ = false; - exception_method_called_ = false; - - app_ = runtime::get()->create_application("application_test"); - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, - std::bind(&someip_application_exception_test::on_message_shutdown, this, - std::placeholders::_1)); - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN+1, - std::bind(&someip_application_exception_test::on_message_exception, this, - std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&someip_application_exception_test::on_state, this, - std::placeholders::_1)); - app_->register_availability_handler( - vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - std::bind(&someip_application_exception_test::on_availability, - this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - - shutdown_thread_ = std::thread(&someip_application_exception_test::send_shutdown_message, this); - - app_->start(); - } - - void TearDown() { - shutdown_thread_.join(); - app_->stop(); - app_.reset(); - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - } - - void on_state(vsomeip::state_type_e _state) { - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - std::lock_guard its_lock(mutex_); - is_registered_ = true; - cv_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - (void)_service; - (void)_instance; - if(_is_available) { - std::lock_guard its_lock(mutex_); - is_available_ = _is_available; - cv_.notify_one(); - } - } - - void on_message_shutdown(const std::shared_ptr& _request) - { - (void)_request; - VSOMEIP_INFO << "Shutdown method was called, going down now."; - app_->clear_all_handler(); - app_->stop(); - } - - void on_message_exception(const std::shared_ptr& _request) - { - (void)_request; - { - std::lock_guard its_lock(mutex_); - exception_method_called_ = true; - cv_.notify_one(); - } - throw std::invalid_argument("something went terribly wrong"); - } - - void send_shutdown_message() { - { - std::unique_lock its_lock(mutex_); - while(!is_registered_) { - cv_.wait(its_lock); - } - app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID); - app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID); - while(!is_available_) { - cv_.wait(its_lock); - } - } - - std::shared_ptr r = runtime::get()->create_request(); - // call method which throws exception - r->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - r->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - r->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN+1); - app_->send(r); - - { - std::unique_lock its_lock(mutex_); - while (!exception_method_called_) { - cv_.wait(its_lock); - } - } - - - //shutdown test - r->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - r->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - r->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); - app_->send(r); - } - - bool is_registered_; - bool is_available_; - bool exception_method_called_; - std::shared_ptr app_; - std::condition_variable cv_; - std::mutex mutex_; - std::thread shutdown_thread_; -}; - -/** - * @test Stop the application through a method invoked from a dispatcher thread - */ -TEST_F(someip_application_shutdown_test, stop_application_from_dispatcher_thread) { - -} - -/** - * @test Catch unhandled exceptions from invoked handlers - */ -TEST_F(someip_application_exception_test, catch_exception_in_invoked_handler) { - -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif - - - - diff --git a/test/application_tests/application_test_availability.cpp b/test/application_tests/application_test_availability.cpp deleted file mode 100644 index 06fd33e..0000000 --- a/test/application_tests/application_test_availability.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include - -#include "application_test_client_availability.cpp" -#include "application_test_service.cpp" -#include "application_test_daemon.cpp" - -TEST(someip_application_test_availability, register_availability_handlers) -{ - // start application acting as daemon - application_test_daemon its_daemon; - - // start receiver service - application_test_service its_receiver(application_test::service); - - // start client - application_test_client_availability its_client(application_test::service); - int counter(0); - while (!its_client.all_availability_handlers_called() && counter < 500) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - counter++; - } - - //shutdown - its_receiver.stop(); - its_client.stop(); - its_daemon.stop(); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/application_tests/application_test_availability_starter.sh b/test/application_tests/application_test_availability_starter.sh deleted file mode 100755 index 645e347..0000000 --- a/test/application_tests/application_test_availability_starter.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_CONFIGURATION=application_test_single_process.json -./application_test_availability - - exit $? \ No newline at end of file diff --git a/test/application_tests/application_test_client.cpp b/test/application_tests/application_test_client.cpp deleted file mode 100644 index 30d0084..0000000 --- a/test/application_tests/application_test_client.cpp +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "application_test_globals.hpp" - -class application_test_client { -public: - application_test_client(struct application_test::service_info _service_info) : - service_info_(_service_info), - app_(vsomeip::runtime::get()->create_application("client")), - wait_until_registered_(true), - wait_until_service_available_(true), - wait_for_stop_(true), - received_responses_(0), - sent_requests_(0), - stop_called_(false), - stop_thread_(std::bind(&application_test_client::wait_for_stop, this)), - send_thread_(std::bind(&application_test_client::send, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&application_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, - std::bind(&application_test_client::on_message, this, - std::placeholders::_1)); - - // register availability for all other services and request their event. - app_->register_availability_handler(service_info_.service_id, - service_info_.instance_id, - std::bind(&application_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - app_->request_service(service_info_.service_id, - service_info_.instance_id); - std::promise its_promise; - application_thread_ = std::thread([&](){ - its_promise.set_value(true); - app_->start(); - }); - EXPECT_TRUE(its_promise.get_future().get()); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - - ~application_test_client() { - send_thread_.join(); - stop_thread_.join(); - application_thread_.join(); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - VSOMEIP_INFO << "Service [" << std::setw(4) - << std::setfill('0') << std::hex << _service << "." << _instance - << "] is " << (_is_available ? "available":"not available") << "."; - std::lock_guard its_lock(mutex_); - if(_is_available) { - wait_until_service_available_ = false; - condition_.notify_one(); - } else { - wait_until_service_available_ = true; - condition_.notify_one(); - } - } - - void on_message(const std::shared_ptr &_message) { - ++received_responses_; - EXPECT_EQ(service_info_.service_id, _message->get_service()); - EXPECT_EQ(service_info_.method_id, _message->get_method()); - EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - VSOMEIP_INFO << "Received a response with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_session() << "]"; - } - - void send() { - std::unique_lock its_lock(mutex_); - while (wait_until_registered_ && !stop_called_) { - condition_.wait_for(its_lock, std::chrono::milliseconds(100)); - } - - while (wait_until_service_available_ && !stop_called_) { - condition_.wait_for(its_lock, std::chrono::milliseconds(100)); - } - its_lock.unlock(); - its_lock.release(); - - for (;;) { - bool send(false); - { - std::lock_guard its_lock(mutex_); - send = !wait_until_service_available_; - } - if (send && !stop_called_) { - std::shared_ptr its_req = vsomeip::runtime::get()->create_request(); - its_req->set_service(service_info_.service_id); - its_req->set_instance(service_info_.instance_id); - its_req->set_method(service_info_.method_id); - app_->send(its_req); - ++sent_requests_; - VSOMEIP_INFO << "Sent a request to the service!"; - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } else { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } - if(stop_called_) { - break; - } - } - } - - void wait_for_stop() { - std::unique_lock its_lock(stop_mutex_); - while (wait_for_stop_) { - stop_condition_.wait(its_lock); - } - VSOMEIP_INFO << "going down"; - app_->clear_all_handler(); - app_->stop(); - } - - void stop(bool check) { - stop_called_ = true; - std::lock_guard its_lock(stop_mutex_); - wait_for_stop_ = false; - VSOMEIP_INFO << "going down. Sent " << sent_requests_ - << " requests and received " << received_responses_ - << " responses. Delta: " << sent_requests_ - received_responses_; - std::uint32_t counter(0); - if (check) { - while(sent_requests_ == 0 || sent_requests_ < received_responses_) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - if(++counter > 50) { - break; - } - } - EXPECT_GT(sent_requests_, 0u); - EXPECT_GT(received_responses_, 0u); - EXPECT_EQ(sent_requests_, received_responses_); - } - stop_condition_.notify_one(); - } - -private: - struct application_test::service_info service_info_; - std::shared_ptr app_; - - bool wait_until_registered_; - bool wait_until_service_available_; - std::mutex mutex_; - std::condition_variable condition_; - - bool wait_for_stop_; - std::mutex stop_mutex_; - std::condition_variable stop_condition_; - - std::atomic received_responses_; - std::atomic sent_requests_; - std::atomic stop_called_; - - std::thread stop_thread_; - std::thread send_thread_; - std::thread application_thread_; -}; diff --git a/test/application_tests/application_test_client_availability.cpp b/test/application_tests/application_test_client_availability.cpp deleted file mode 100644 index 16fe87b..0000000 --- a/test/application_tests/application_test_client_availability.cpp +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "application_test_globals.hpp" - -class application_test_client_availability { -public: - application_test_client_availability(struct application_test::service_info _service_info) : - service_info_(_service_info), - app_(vsomeip::runtime::get()->create_application("client")), - wait_until_registered_(true), - all_availability_handlers_called_(false), - run_thread_(std::bind(&application_test_client_availability::run, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&application_test_client_availability::on_state, this, - std::placeholders::_1)); - - // register availability handler for every possiblity of - // ANY_SERVICE, ANY_INSTANCE, ANY_MAJOR, ANY_MINOR - for (std::uint32_t i = 0; i < 16; i++) { - vsomeip::service_t its_service = (i & 0x8) ? service_info_.service_id : vsomeip::ANY_SERVICE; - vsomeip::instance_t its_instance = (i & 0x4) ? service_info_.instance_id : vsomeip::ANY_INSTANCE; - vsomeip::major_version_t its_major = (i & 0x2) ? service_info_.major_version : vsomeip::ANY_MAJOR; - vsomeip::minor_version_t its_minor = (i & 0x1) ? service_info_.minor_version : vsomeip::ANY_MINOR; - app_->register_availability_handler(its_service, - its_instance, - std::bind(&application_test_client_availability::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, i), - its_major, its_minor); - VSOMEIP_DEBUG << "Registering: " - << std::setw(4) << std::setfill('0') << std::hex << its_service << "." - << std::setw(4) << std::setfill('0') << std::hex << its_instance << "." - << std::setw(2) << std::setfill('0') << std::hex << (std::uint32_t)its_major << "." - << std::setw(4) << std::setfill('0') << std::hex << its_minor << "." - << i; - - } - app_->register_availability_handler(service_info_.service_id, - service_info_.instance_id, - std::bind(&application_test_client_availability::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, 16), - service_info_.major_version, vsomeip::DEFAULT_MINOR); - VSOMEIP_DEBUG << "Registering: " - << std::setw(4) << std::setfill('0') << std::hex << service_info_.service_id << "." - << std::setw(4) << std::setfill('0') << std::hex << service_info_.instance_id << "." - << std::setw(2) << std::setfill('0') << std::hex << (std::uint32_t)service_info_.service_id << "." - << std::setw(4) << std::setfill('0') << std::hex << vsomeip::DEFAULT_MINOR << "." - << 16; - app_->request_service(service_info_.service_id, - service_info_.instance_id); - std::promise its_promise; - application_thread_ = std::thread([&](){ - its_promise.set_value(true); - app_->start(); - }); - EXPECT_TRUE(its_promise.get_future().get()); - } - - ~application_test_client_availability() { - run_thread_.join(); - application_thread_.join(); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available, - std::uint32_t _handler_index) - { - VSOMEIP_DEBUG<< "Service [" << std::setw(4) << std::setfill('0') << std::hex - << _service << "." << std::setw(4) << std::setfill('0') << _instance << "] is " - << (_is_available ? "available." : "NOT available.") << ". " - << _handler_index; - if(service_info_.service_id == _service - && service_info_.instance_id == _instance) { - std::lock_guard its_lock(availability_handler_called_mutex_); - availability_handler_called_[_handler_index] = _is_available; - availability_condition_.notify_one(); - } - } - - void run() { - { - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - } - while(!app_->is_available(service_info_.service_id, - service_info_.instance_id, service_info_.major_version, - service_info_.minor_version)) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - for (std::uint32_t i = 0; i < 16; i++) { - vsomeip::service_t its_service = (i & 0x8) ? service_info_.service_id : vsomeip::ANY_SERVICE; - vsomeip::instance_t its_instance = (i & 0x4) ? service_info_.instance_id : vsomeip::ANY_INSTANCE; - vsomeip::major_version_t its_major = (i & 0x2) ? service_info_.major_version : vsomeip::ANY_MAJOR; - vsomeip::minor_version_t its_minor = (i & 0x1) ? service_info_.minor_version : vsomeip::ANY_MINOR; - - VSOMEIP_DEBUG << "Calling is_available: " - << std::setw(4) << std::setfill('0') << std::hex << its_service << "." - << std::setw(4) << std::setfill('0') << std::hex << its_instance << "." - << std::setw(2) << std::setfill('0') << std::hex << (std::uint32_t)its_major << "." - << std::setw(4) << std::setfill('0') << std::hex << its_minor; - EXPECT_TRUE(app_->is_available(its_service, its_instance, its_major, its_minor)); - - VSOMEIP_DEBUG << "Calling are_available: " - << std::setw(4) << std::setfill('0') << std::hex << its_service << "." - << std::setw(4) << std::setfill('0') << std::hex << its_instance << "." - << std::setw(2) << std::setfill('0') << std::hex << (std::uint32_t)its_major << "." - << std::setw(4) << std::setfill('0') << std::hex << its_minor; - vsomeip::application::available_t are_available; - EXPECT_TRUE(app_->are_available(are_available, its_service, its_instance, its_major, its_minor)); - bool found(false); - auto found_service = are_available.find(service_info_.service_id); - if(found_service != are_available.end()) { - auto found_instance = found_service->second.find(service_info_.instance_id); - if(found_instance != found_service->second.end()) { - auto found_major = found_instance->second.find(service_info_.major_version); - if (found_major != found_instance->second.end()) { - if (found_major->second == service_info_.minor_version) { - found = true; - } - } - } - } - EXPECT_TRUE(found); - - } - { - std::unique_lock its_lock(availability_handler_called_mutex_); - while(!std::all_of(availability_handler_called_.cbegin(), - availability_handler_called_.cend(), - [&](const availability_handler_called_t::value_type &v) { - return v; - })) { - availability_condition_.wait(its_lock); - } - } - VSOMEIP_INFO <<" Everything is available"; - all_availability_handlers_called_ = true; - } - - void stop() { - VSOMEIP_INFO << "going down"; - app_->clear_all_handler(); - app_->stop(); - } - - bool all_availability_handlers_called() const { - return all_availability_handlers_called_; - } - -private: - struct application_test::service_info service_info_; - std::shared_ptr app_; - std::mutex availability_handler_called_mutex_; - std::condition_variable availability_condition_; - typedef std::array availability_handler_called_t; - availability_handler_called_t availability_handler_called_; - - - bool wait_until_registered_; - std::mutex mutex_; - std::condition_variable condition_; - std::atomic all_availability_handlers_called_; - std::thread run_thread_; - std::thread application_thread_; -}; diff --git a/test/application_tests/application_test_daemon.cpp b/test/application_tests/application_test_daemon.cpp deleted file mode 100644 index 2f0b244..0000000 --- a/test/application_tests/application_test_daemon.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include - -#include -#include - -class application_test_daemon { -public: - application_test_daemon() : - app_(vsomeip::runtime::get()->create_application("daemon")) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - std::promise its_promise; - application_thread_ = std::thread([&](){ - its_promise.set_value(true); - app_->start(); - }); - EXPECT_TRUE(its_promise.get_future().get()); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - VSOMEIP_INFO << "Daemon starting"; - } - - ~application_test_daemon() { - application_thread_.join(); - } - - void stop() { - VSOMEIP_INFO << "Daemon stopping"; - app_->stop(); - } - -private: - std::shared_ptr app_; - std::thread application_thread_; -}; diff --git a/test/application_tests/application_test_globals.hpp b/test/application_tests/application_test_globals.hpp deleted file mode 100644 index 7caa9db..0000000 --- a/test/application_tests/application_test_globals.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef APPLICATION_TEST_GLOBALS_HPP_ -#define APPLICATION_TEST_GLOBALS_HPP_ - -namespace application_test { - -struct service_info { - vsomeip::service_t service_id; - vsomeip::instance_t instance_id; - vsomeip::method_t method_id; - vsomeip::event_t event_id; - vsomeip::eventgroup_t eventgroup_id; - vsomeip::method_t shutdown_method_id; - vsomeip::major_version_t major_version; - vsomeip::minor_version_t minor_version; -}; - - -struct service_info service = { 0x1111, 0x1, 0x1111, 0x1111, 0x1000, 0x1404, 0x2, 0x4711 }; - -static constexpr int number_of_messages_to_send = 150; -} - -#endif /* APPLICATION_TEST_GLOBALS_HPP_ */ diff --git a/test/application_tests/application_test_service.cpp b/test/application_tests/application_test_service.cpp deleted file mode 100644 index 77d40cd..0000000 --- a/test/application_tests/application_test_service.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "application_test_globals.hpp" - -class application_test_service { -public: - application_test_service(struct application_test::service_info _service_info) : - service_info_(_service_info), - // service with number 1 uses "routingmanagerd" as application name - // this way the same json file can be reused for all local tests - // including the ones with routingmanagerd - app_(vsomeip::runtime::get()->create_application("service")), - wait_until_registered_(true), - stop_called_(false), - offer_thread_(std::bind(&application_test_service::run, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&application_test_service::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.method_id, - std::bind(&application_test_service::on_request, this, - std::placeholders::_1)); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.shutdown_method_id, - std::bind(&application_test_service::on_shutdown_method_called, this, - std::placeholders::_1)); - std::promise its_promise; - application_thread_ = std::thread([&](){ - its_promise.set_value(true); - app_->start(); - }); - EXPECT_TRUE(its_promise.get_future().get()); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - - ~application_test_service() { - offer_thread_.join(); - application_thread_.join(); - } - - - void offer() { - app_->offer_service(service_info_.service_id, service_info_.instance_id, - service_info_.major_version, service_info_.minor_version); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_request(const std::shared_ptr &_message) { - app_->send(vsomeip::runtime::get()->create_response(_message)); - VSOMEIP_INFO << "Received a request with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_session() << "]"; - } - - void on_shutdown_method_called(const std::shared_ptr &_message) { - (void)_message; - stop(); - } - - void stop() { - stop_called_ = true; - app_->stop_offer_service(service_info_.service_id, service_info_.instance_id, - service_info_.major_version, service_info_.minor_version); - app_->clear_all_handler(); - app_->stop(); - } - - void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; - std::unique_lock its_lock(mutex_); - while (wait_until_registered_ && !stop_called_) { - condition_.wait_for(its_lock, std::chrono::milliseconds(100)); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - } - -private: - struct application_test::service_info service_info_; - std::shared_ptr app_; - - bool wait_until_registered_; - std::mutex mutex_; - std::condition_variable condition_; - std::atomic stop_called_; - std::thread offer_thread_; - std::thread application_thread_; -}; diff --git a/test/application_tests/application_test_single_process.cpp b/test/application_tests/application_test_single_process.cpp deleted file mode 100644 index b4497a7..0000000 --- a/test/application_tests/application_test_single_process.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include "application_test_service.cpp" -#include "application_test_client.cpp" -#include "application_test_daemon.cpp" - -TEST(someip_application_test_single_process, notify_increasing_counter) -{ - // start application acting as daemon (rm_stub) - auto its_daemon = std::make_shared(); - - // start receiver service (rm_proxy) - application_test_service its_receiver(application_test::service); - - // stop the daemon (rm_stub goes away) - its_daemon->stop(); - its_daemon.reset(); - // restart client which tries to communicate with service multiple times - // thus it will always be the new routing manager - for (int var = 0; var < 10; ++var) { - // every time the client is restarted it becomes the rm_stub again - application_test_client its_client(application_test::service); - if(var != 9) { - its_client.stop(false); - } else { - // for the last iteration we sleep to make sure the communication - // between the client and the service can be established - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); - its_client.stop(true); - } - } - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - its_receiver.on_shutdown_method_called(vsomeip::runtime::get()->create_message()); -} - - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/application_tests/application_test_single_process.json b/test/application_tests/application_test_single_process.json deleted file mode 100644 index b604d9a..0000000 --- a/test/application_tests/application_test_single_process.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "unicast":"127.0.0.1", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/someip.log" - }, - "dlt":"false" - } -} diff --git a/test/application_tests/application_test_single_process_starter.sh b/test/application_tests/application_test_single_process_starter.sh deleted file mode 100755 index 3919358..0000000 --- a/test/application_tests/application_test_single_process_starter.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -FAIL=0 - -export VSOMEIP_CONFIGURATION=application_test_single_process.json -./application_test_single_process - -if [ $? -ne 0 ] -then - ((FAIL+=1)) -fi - -# Check if both exited successfully -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/application_tests/application_test_starter.sh b/test/application_tests/application_test_starter.sh deleted file mode 100755 index bb17515..0000000 --- a/test/application_tests/application_test_starter.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -FAIL=0 - -export VSOMEIP_CONFIGURATION=application_test_no_dispatch_threads.json -./application_test - -if [ $? -ne 0 ] -then - ((FAIL+=1)) -fi - -export VSOMEIP_CONFIGURATION=application_test.json -./application_test - -if [ $? -ne 0 ] -then - ((FAIL+=1)) -fi - -cat < + +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/test/benchmark_tests/security_tests/bm_check_credentials.cpp b/test/benchmark_tests/security_tests/bm_check_credentials.cpp new file mode 100644 index 0000000..756cd5f --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_check_credentials.cpp @@ -0,0 +1,106 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace { + vsomeip_v3::client_t client = 1; + vsomeip_v3::uid_t invalid_uid = 1; + vsomeip_v3::uid_t valid_uid = 4004201; + vsomeip_v3::gid_t invalid_gid = 1; + vsomeip_v3::gid_t valid_gid = 4004200; +} + +static void BM_check_credentials_policies_not_loaded(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + // create security clients + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) + its_manager->check_credentials(client, &its_sec_client_invalid); +} + +static void BM_check_credentials_policies_loaded_invalid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + // create security clients + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) + its_manager->check_credentials(client, &its_sec_client_invalid); +} + +static void BM_check_credentials_policies_loaded_valid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + + for (auto _ : state) + its_manager->check_credentials(client, &its_sec_client_valid); +} + +static void BM_check_credentials_policies_loaded_audit_mode_invalid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + // create security clients + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) + its_manager->check_credentials(client, &its_sec_client_invalid); +} + +static void BM_check_credentials_policies_loaded_audit_mode_valid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + + for (auto _ : state) + its_manager->check_credentials(client, &its_sec_client_valid); +} + +BENCHMARK(BM_check_credentials_policies_not_loaded); +BENCHMARK(BM_check_credentials_policies_loaded_invalid_values); +BENCHMARK(BM_check_credentials_policies_loaded_valid_values); +BENCHMARK(BM_check_credentials_policies_loaded_audit_mode_invalid_values); +BENCHMARK(BM_check_credentials_policies_loaded_audit_mode_valid_values); \ No newline at end of file diff --git a/test/benchmark_tests/security_tests/bm_check_routing_credentials.cpp b/test/benchmark_tests/security_tests/bm_check_routing_credentials.cpp new file mode 100644 index 0000000..ed6ed57 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_check_routing_credentials.cpp @@ -0,0 +1,99 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace{ +vsomeip_v3::uid_t invalid_uid = 1; +vsomeip_v3::uid_t valid_uid = 4003017; +vsomeip_v3::gid_t invalid_gid = 1; +vsomeip_v3::gid_t valid_gid = 5002; +} + +static void BM_check_routing_credentials_policies_not_loaded(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) + security->check_routing_credentials(&its_sec_client_invalid); +} + +static void BM_check_routing_credentials_policies_loaded_invalid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) + security->check_routing_credentials(&its_sec_client_invalid); +} + +static void BM_check_routing_credentials_policies_loaded_valid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) + security->check_routing_credentials(&its_sec_client_valid); +} + +static void BM_check_routing_credentials_policies_loaded_lazy_load_invalid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + security->load(e, true); + } + + for (auto _ : state) + security->check_routing_credentials(&its_sec_client_invalid); +} + +static void BM_check_routing_credentials_policies_loaded_lazy_load_valid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + security->load(e, true); + } + + for (auto _ : state) + security->check_routing_credentials(&its_sec_client_valid); +} + +BENCHMARK(BM_check_routing_credentials_policies_not_loaded); +BENCHMARK(BM_check_routing_credentials_policies_loaded_invalid_values); +BENCHMARK(BM_check_routing_credentials_policies_loaded_valid_values); +BENCHMARK(BM_check_routing_credentials_policies_loaded_lazy_load_invalid_values); +BENCHMARK(BM_check_routing_credentials_policies_loaded_lazy_load_valid_values); diff --git a/test/benchmark_tests/security_tests/bm_get_client_to_sec_client_mapping.cpp b/test/benchmark_tests/security_tests/bm_get_client_to_sec_client_mapping.cpp new file mode 100644 index 0000000..aa80406 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_get_client_to_sec_client_mapping.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace{ +vsomeip_v3::client_t client = 10; +vsomeip_v3::client_t alternate_client = 11; +vsomeip_v3::uid_t uid_1 = 4003030; +vsomeip_v3::gid_t gid_1 = 4003032; +vsomeip_v3::uid_t uid_2 = 1; +vsomeip_v3::gid_t gid_2 = 1; +vsomeip_v3::uid_t uid_3 = 2; +vsomeip_v3::gid_t gid_3 = 2; +} + +static void BM_get_client_to_sec_client_mapping_valid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid_1 = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_uid_gid_2 = utility::create_uds_client(uid_2, gid_2); + + // add client and security client mappings + security->store_client_to_sec_client_mapping(client, &its_sec_client_uid_gid_1); + + for (auto _ : state) { + security->get_client_to_sec_client_mapping(client, its_sec_client_uid_gid_2); + } + + vsomeip_sec_client_t its_sec_client_uid_gid_3 = utility::create_uds_client(uid_3, gid_3); + + // add alternate client and security client + security->store_client_to_sec_client_mapping(alternate_client, &its_sec_client_uid_gid_1); + + for (auto _ : state) { + security->get_client_to_sec_client_mapping(alternate_client, its_sec_client_uid_gid_3); + } +} + +static void BM_get_client_to_sec_client_mapping_invalid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid_1 = utility::create_uds_client(uid_1, gid_1); + + for (auto _ : state) { + security->get_client_to_sec_client_mapping(client, its_sec_client_uid_gid_1); + } + + for (auto _ : state) { + security->get_client_to_sec_client_mapping(alternate_client, its_sec_client_uid_gid_1); + } +} + +BENCHMARK(BM_get_client_to_sec_client_mapping_valid_values); +BENCHMARK(BM_get_client_to_sec_client_mapping_invalid_values); diff --git a/test/benchmark_tests/security_tests/bm_get_clients.cpp b/test/benchmark_tests/security_tests/bm_get_clients.cpp new file mode 100644 index 0000000..091c9e1 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_get_clients.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace{ +std::unordered_set clients; +std::unordered_set local_clients; +vsomeip_v3::client_t client_1 = 10; +vsomeip_v3::client_t client_2 = 11; +vsomeip_v3::client_t client_3 = 12; +vsomeip_v3::uid_t uid = 4003030; +vsomeip_v3::gid_t gid = 4003032; +} + +static void BM_get_clients(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid = utility::create_uds_client(uid, gid); + + // Loop to do the benchmark test the get with an empty clients list. + for (auto _ : state) { + security->get_clients(uid, gid, clients); + } + + local_clients.insert(client_1); + security->store_client_to_sec_client_mapping(client_1, &its_sec_client_uid_gid); + + // Loop to do the benchmark test the get with 1 client on the list + for (auto _ : state) { + security->get_clients(uid, gid, clients); + } + + // Repeat with two more clients. + security->store_client_to_sec_client_mapping(client_2, &its_sec_client_uid_gid); + security->store_client_to_sec_client_mapping(client_3, &its_sec_client_uid_gid); + + local_clients.insert(client_2); + local_clients.insert(client_3); + + //Loop to do the benchmark test the get with 3 clients on the list + for (auto _ : state) { + security->get_clients(uid, gid, clients); + } +} + +BENCHMARK(BM_get_clients); diff --git a/test/benchmark_tests/security_tests/bm_get_sec_client_to_clients_mapping.cpp b/test/benchmark_tests/security_tests/bm_get_sec_client_to_clients_mapping.cpp new file mode 100644 index 0000000..71a517a --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_get_sec_client_to_clients_mapping.cpp @@ -0,0 +1,60 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace{ +vsomeip_v3::client_t client = 10; +vsomeip_v3::uid_t uid_1 = 4003030; +vsomeip_v3::gid_t gid_1 = 4003032; +vsomeip_v3::uid_t uid_2 = 1; +vsomeip_v3::gid_t gid_2 = 1; +} + +static void BM_get_sec_client_to_clients_mapping_valid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_uid_gid_alternate = utility::create_uds_client(uid_2, gid_2); + + // Add client and uid_gid mappings. + security->store_sec_client_to_client_mapping(&its_sec_client_uid_gid, client); + + std::set clients_1; + for (auto _ : state) { + security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid, clients_1); + } + + // Add alternate client and uid_gid mappings. + security->store_sec_client_to_client_mapping(&its_sec_client_uid_gid_alternate, client); + + std::set clients_2; + for (auto _ : state) { + security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid_alternate, clients_2); + } +} + +static void BM_get_sec_client_to_clients_mapping_invalid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_uid_gid_alternate = utility::create_uds_client(uid_2, gid_2); + + std::set clients; + for (auto _ : state) { + security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid, clients); + } + + for (auto _ : state) { + security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid_alternate, clients); + } +} + +BENCHMARK(BM_get_sec_client_to_clients_mapping_valid_values); +BENCHMARK(BM_get_sec_client_to_clients_mapping_invalid_values); diff --git a/test/benchmark_tests/security_tests/bm_is_client_allowed.cpp b/test/benchmark_tests/security_tests/bm_is_client_allowed.cpp new file mode 100644 index 0000000..fbbbde3 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_is_client_allowed.cpp @@ -0,0 +1,195 @@ +#include + +#include "../../common/utility.hpp" + +namespace { + vsomeip_v3::client_t client = 1; + + vsomeip_v3::uid_t uid_1 = 4003031; + vsomeip_v3::gid_t gid_1 = 4003031; + vsomeip_v3::service_t service_1 = 0xf913; + + vsomeip_v3::instance_t instance = 0x03; + vsomeip_v3::method_t method = 0x04; + + vsomeip_v3::gid_t invalid_uid = 1; + vsomeip_v3::gid_t invalid_gid = 1; + + vsomeip_v3::gid_t deny_uid = 9999; + vsomeip_v3::gid_t deny_gid = 9999; + vsomeip_v3::service_t deny_service = 0x40; +} + +static void BM_is_client_allowed_policies_not_loaded(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) + { + its_manager->is_client_allowed(&its_sec_client_invalid, service_1, instance, method); + } +} + +static void BM_is_client_allowed_policies_loaded_valid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid_1, gid_1); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client, service_1, instance, method); + } +} + +static void BM_is_client_allowed_cache_policies_loaded(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid_1, gid_1); + + its_manager->is_client_allowed(&its_sec_client, service_1, instance, method); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client, service_1, instance, method); + } +} + +static void BM_is_client_allowed_policies_loaded_invalid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client_invalid, service_1, instance, method); + } +} + +static void BM_is_client_allowed_policies_loaded_deny_valid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client_deny, deny_service, instance, method); + } +} + +static void BM_is_client_allowed_policies_loaded_audit_mode_valid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid_1, gid_1); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client, client, service_1, instance, method); + } +} + +static void BM_is_client_allowed_cache_policies_loaded_audit_mode(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid_1, gid_1); + + its_manager->is_client_allowed(&its_sec_client, service_1, instance, method); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client, service_1, instance, method); + } +} + +static void BM_is_client_allowed_policies_loaded_audit_mode_invalid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client_invalid, service_1, instance, method); + } +} + +static void BM_is_client_allowed_policies_loaded_audit_mode_deny_valid_values(benchmark::State& state) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + + for (auto _ : state) { + its_manager->is_client_allowed(&its_sec_client_deny, deny_service, instance, method); + } +} + +BENCHMARK(BM_is_client_allowed_policies_not_loaded); +BENCHMARK(BM_is_client_allowed_policies_loaded_valid_values); +BENCHMARK(BM_is_client_allowed_cache_policies_loaded); +BENCHMARK(BM_is_client_allowed_policies_loaded_invalid_values); +BENCHMARK(BM_is_client_allowed_policies_loaded_deny_valid_values); +BENCHMARK(BM_is_client_allowed_policies_loaded_audit_mode_valid_values); +BENCHMARK(BM_is_client_allowed_cache_policies_loaded_audit_mode); +BENCHMARK(BM_is_client_allowed_policies_loaded_audit_mode_invalid_values); +BENCHMARK(BM_is_client_allowed_policies_loaded_audit_mode_deny_valid_values); \ No newline at end of file diff --git a/test/benchmark_tests/security_tests/bm_is_offer_allowed.cpp b/test/benchmark_tests/security_tests/bm_is_offer_allowed.cpp new file mode 100644 index 0000000..4b8299f --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_is_offer_allowed.cpp @@ -0,0 +1,167 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace { + +vsomeip_v3::uid_t uid_1 = 4003016; +vsomeip_v3::gid_t gid_1 = 4003016; +vsomeip_v3::service_t service_1 = 0xf8c2; + +vsomeip_v3::service_t deny_service = 0x40; + +vsomeip_v3::instance_t instance = 0x03; + +vsomeip_v3::uid_t invalid_uid = 1; +vsomeip_v3::gid_t invalid_gid = 1; + +vsomeip_v3::gid_t deny_uid = 9000; +vsomeip_v3::gid_t deny_gid = 9000; +} + +static void BM_is_offer_allowed_policies_not_loaded(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (auto _ : state) + { + security->is_offer_allowed(&its_sec_client_invalid, service_1, instance); + } +} + +static void BM_is_offer_allowed_policies_loaded_valid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(uid_1, gid_1); + + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) { + security->is_offer_allowed(&its_sec_client_valid, service_1, instance); + } +} + +static void BM_is_offer_allowed_policies_loaded_invalid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) { + security->is_offer_allowed(&its_sec_client_invalid, service_1, instance); + } +} + +static void BM_is_offer_allowed_policies_loaded_deny_valid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) { + security->is_offer_allowed(&its_sec_client_deny, deny_service, instance); + } +} + +static void BM_is_offer_allowed_policies_loaded_audit_mode_valid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(uid_1, gid_1); + + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) { + security->is_offer_allowed(&its_sec_client_valid, service_1, instance); + } +} + +static void BM_is_offer_allowed_policies_loaded_audit_mode_invalid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) { + security->is_offer_allowed(&its_sec_client_invalid, service_1, instance); + } +} + +static void BM_is_offer_allowed_policies_loaded_audit_mode_deny_valid_values(benchmark::State& state) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + utility::force_check_credentials(policy_elements, "false"); + + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + + for (const auto& e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) { + security->is_offer_allowed(&its_sec_client_deny, deny_service, instance); + } +} + +BENCHMARK(BM_is_offer_allowed_policies_not_loaded); +BENCHMARK(BM_is_offer_allowed_policies_loaded_valid_values); +BENCHMARK(BM_is_offer_allowed_policies_loaded_invalid_values); +BENCHMARK(BM_is_offer_allowed_policies_loaded_deny_valid_values); +BENCHMARK(BM_is_offer_allowed_policies_loaded_audit_mode_valid_values); +BENCHMARK(BM_is_offer_allowed_policies_loaded_audit_mode_invalid_values); +BENCHMARK(BM_is_offer_allowed_policies_loaded_audit_mode_deny_valid_values); diff --git a/test/benchmark_tests/security_tests/bm_is_policy_update_allowed.cpp b/test/benchmark_tests/security_tests/bm_is_policy_update_allowed.cpp new file mode 100644 index 0000000..8e3ab4d --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_is_policy_update_allowed.cpp @@ -0,0 +1,358 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" +namespace { +std::string configuration_file { "/vsomeip/0_0/vsomeip_security.json" }; + +vsomeip_v3::uid_t valid_uid { 0 }; +vsomeip_v3::uid_t invalid_uid { 1234567 }; + +vsomeip_v3::gid_t valid_gid { 0 }; + +vsomeip_v3::service_t valid_service { 0xf913 }; +vsomeip_v3::service_t invalid_service { 0x41 }; +} + +static void BM_is_policy_update_allowed_valid_uid_no_requests(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + for (auto _ : state) { + security->is_policy_update_allowed(valid_uid, policy); + } +} + +static void BM_is_policy_update_allowed_invalid_uid_no_requests(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + for (auto _ : state) { + security->is_policy_update_allowed(invalid_uid, policy); + } +} + +static void BM_is_policy_update_allowed_valid_uid_valid_requests(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map< + vsomeip::instance_t, + boost::icl::interval_set + >its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + valid_service, valid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + for (auto _ : state) { + security->is_policy_update_allowed(valid_uid, policy); + } +} + +static void BM_is_policy_update_allowed_invalid_uid_valid_requests(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map> + its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + valid_service, valid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + for (auto _ : state) { + security->is_policy_update_allowed(invalid_uid, policy); + } +} + +static void BM_is_policy_update_allowed_valid_uid_invalid_requests(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map< + vsomeip::instance_t, + boost::icl::interval_set + >its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + invalid_service, invalid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + for (auto _ : state) { + security->is_policy_update_allowed(valid_uid, policy); + } +} + +static void BM_is_policy_update_allowed_invalid_uid_invalid_requests(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map< + vsomeip::instance_t, + boost::icl::interval_set + >its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + invalid_service, invalid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + for (auto _ : state) { + security->is_policy_update_allowed(invalid_uid, policy); + } +} + +static void BM_is_policy_update_allowed_invalid_uid_ignore_whitelist(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { false }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + for (auto _ : state) { + security->is_policy_update_allowed(invalid_uid, policy); + } +} + +static void +BM_is_policy_update_allowed_valid_uid_invalid_request_ignore_whitelist(benchmark::State &state) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + const bool check_whitelist { false }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map< + vsomeip::instance_t, + boost::icl::interval_set + >its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + invalid_service, invalid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + for (auto _ : state) { + security->is_policy_update_allowed(valid_uid, policy); + } +} + +BENCHMARK(BM_is_policy_update_allowed_valid_uid_no_requests); +BENCHMARK(BM_is_policy_update_allowed_invalid_uid_no_requests); +BENCHMARK(BM_is_policy_update_allowed_valid_uid_valid_requests); +BENCHMARK(BM_is_policy_update_allowed_invalid_uid_valid_requests); +BENCHMARK(BM_is_policy_update_allowed_valid_uid_invalid_requests); +BENCHMARK(BM_is_policy_update_allowed_invalid_uid_invalid_requests); +BENCHMARK(BM_is_policy_update_allowed_invalid_uid_ignore_whitelist); +BENCHMARK(BM_is_policy_update_allowed_valid_uid_invalid_request_ignore_whitelist); diff --git a/test/benchmark_tests/security_tests/bm_load_policies.cpp b/test/benchmark_tests/security_tests/bm_load_policies.cpp new file mode 100644 index 0000000..bfafd7e --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_load_policies.cpp @@ -0,0 +1,98 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include "../../common/utility.hpp" +#include + +namespace { +std::string configuration_file { "/vsomeip/0_0/vsomeip_security.json" }; +} + +// Since this set of tests check a private method, there is the need to indirectly change the +// parameters used by load_policies, and check its changes using other methods. +// The remove_security_policy method checks if there is any loaded policy. +// The is_audit method checks the check_credentials value. +// No test was created for allow_remote_clients because it was inacessible. + +static void BM_load_policies_loaded_policies(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Using load function to indirectly call load_policies. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_policies_no_policies(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Remove all the policies from the file. + policy_elements.at(0).tree_.get_child("security").erase("policies"); + + // Using load function to indirectly call load_policies. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_policies_check_credentials_true(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies without the check credentials value set. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the check credentials value as false. + bool check_credentials_value {true}; + policy_elements.at(0).tree_.add("security.check_credentials", check_credentials_value); + + // Using load function to indirectly call load_policies. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_policies_check_credentials_false(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies without the check credentials value set. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the check credentials value as false. + bool check_credentials_value {false}; + policy_elements.at(0).tree_.add("security.check_credentials", check_credentials_value); + + // Using load function to indirectly call load_policies. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +BENCHMARK(BM_load_policies_loaded_policies); +BENCHMARK(BM_load_policies_no_policies); +BENCHMARK(BM_load_policies_check_credentials_true); +BENCHMARK(BM_load_policies_check_credentials_false); diff --git a/test/benchmark_tests/security_tests/bm_load_security_update_whitelist.cpp b/test/benchmark_tests/security_tests/bm_load_security_update_whitelist.cpp new file mode 100644 index 0000000..9c9a43d --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_load_security_update_whitelist.cpp @@ -0,0 +1,144 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include "../../common/utility.hpp" +namespace { +std::string configuration_file { "/vsomeip/0_0/vsomeip_security.json" }; +} + +// Since this set of tests check a private method, there is the need to indirectly change the +// parameters used by load_security_update_whitelist, and check its changes using other methods. +// The is_policy_removal_allowed method checks if a selected uid is present in the whitelist. +// The is_policy_update_allowed method checks if a selected service_id is present in the whitelist. + +static void BM_load_security_update_whitelist_check_no_uids_loaded(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + std::vector user_ids; + + std::vector services; + utility::get_policy_services(policy_elements.at(0), services); + + // Add a security whitelist with an empty list of user uids. + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_security_update_whitelist_check_uids_loaded(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + std::vector user_ids; + utility::get_policy_uids(policy_elements.at(0), user_ids); + + std::vector services; + utility::get_policy_services(policy_elements.at(0), services); + + // Add a security whitelist with a list of uids loaded + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_security_update_whitelist_check_no_service_ids_loaded(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies with an empty service id vector. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + std::vector user_ids; + utility::get_policy_uids(policy_elements.at(0), user_ids); + + std::vector services; + + // Add a security whitelist with an empty list of user uids. + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_security_update_whitelist_check_service_ids_loaded(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + std::vector user_ids; + utility::get_policy_uids(policy_elements.at(0), user_ids); + + std::vector services; + utility::get_policy_services(policy_elements.at(0), services); + + // Add a security whitelist with list of service ids loaded. + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +static void BM_load_security_update_whitelist_check_whitelist_disabled(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + std::vector user_ids; + utility::get_policy_uids(policy_elements.at(0), user_ids); + + std::vector services; + utility::get_policy_services(policy_elements.at(0), services); + + // Add a security whitelist with check_whitelist disabled + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, false); + + // Using load function to indirectly call load_security_update_whitelist. + for (auto _ : state) { + security->load(policy_elements.at(0)); + } +} + +BENCHMARK(BM_load_security_update_whitelist_check_no_uids_loaded); +BENCHMARK(BM_load_security_update_whitelist_check_no_service_ids_loaded); +BENCHMARK(BM_load_security_update_whitelist_check_uids_loaded); +BENCHMARK(BM_load_security_update_whitelist_check_service_ids_loaded); +BENCHMARK(BM_load_security_update_whitelist_check_whitelist_disabled); diff --git a/test/benchmark_tests/security_tests/bm_remove_client_to_sec_client_mapping.cpp b/test/benchmark_tests/security_tests/bm_remove_client_to_sec_client_mapping.cpp new file mode 100644 index 0000000..9a529eb --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_remove_client_to_sec_client_mapping.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace{ +vsomeip_v3::client_t client = 10; +vsomeip_v3::uid_t uid = 4003030; +vsomeip_v3::gid_t gid = 4003032; + +std::pair client_uid_gid{uid, gid}; +} + +static void BM_remove_client_to_sec_client_mapping_invalid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid, gid); + + for (auto _ : state) { + security->get_client_to_sec_client_mapping(client, its_sec_client); + } + + for (auto _ : state) { + security->remove_client_to_sec_client_mapping(client); + } +} + +static void BM_remove_client_to_sec_client_mapping_valid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid, gid); + + security->store_client_to_sec_client_mapping(client, &its_sec_client); + security->store_sec_client_to_client_mapping(&its_sec_client, client); + + for (auto _ : state) { + security->get_client_to_sec_client_mapping(client, its_sec_client); + } + + for (auto _ : state) { + security->remove_client_to_sec_client_mapping(client); + } +} + +BENCHMARK(BM_remove_client_to_sec_client_mapping_invalid_values); +BENCHMARK(BM_remove_client_to_sec_client_mapping_valid_values); diff --git a/test/benchmark_tests/security_tests/bm_remove_security_policy.cpp b/test/benchmark_tests/security_tests/bm_remove_security_policy.cpp new file mode 100644 index 0000000..c56cfd6 --- /dev/null +++ b/test/benchmark_tests/security_tests/bm_remove_security_policy.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace +{ + vsomeip_v3::uid_t invalid_uid = 1; + vsomeip_v3::uid_t valid_uid = 4002200; + vsomeip_v3::gid_t invalid_gid = 1; + vsomeip_v3::gid_t valid_gid = 4003014; +} + +static void BM_remove_security_policy_policies_not_loaded(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + for (auto _ : state) + security->remove_security_policy(invalid_uid, invalid_gid); +} + +static void BM_remove_security_policy_policies_loaded_invalid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), + policy_elements, its_failed); + for (const auto &e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) + security->remove_security_policy(invalid_uid, invalid_gid); +} + +static void BM_remove_security_policy_policies_loaded_valid_values(benchmark::State &state) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), + policy_elements, its_failed); + for (const auto &e : policy_elements) { + security->load(e, false); + } + + for (auto _ : state) + security->remove_security_policy(valid_uid, valid_gid); +} + +BENCHMARK(BM_remove_security_policy_policies_not_loaded); +BENCHMARK(BM_remove_security_policy_policies_loaded_invalid_values); +BENCHMARK(BM_remove_security_policy_policies_loaded_valid_values); diff --git a/test/big_payload_tests/big_payload_test_client.cpp b/test/big_payload_tests/big_payload_test_client.cpp deleted file mode 100644 index 48ee6c2..0000000 --- a/test/big_payload_tests/big_payload_test_client.cpp +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "big_payload_test_client.hpp" -#include "big_payload_test_globals.hpp" - -big_payload_test_client::big_payload_test_client( - bool _use_tcp, big_payload_test::test_mode _test_mode) : - app_(vsomeip::runtime::get()->create_application("big_payload_test_client")), - request_(vsomeip::runtime::get()->create_request(_use_tcp)), - blocked_(false), - is_available_(false), - test_mode_(_test_mode), - number_of_messages_to_send_( - test_mode_ == big_payload_test::test_mode::RANDOM ? - big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES_RANDOM : - big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES), - number_of_sent_messages_(0), - number_of_acknowledged_messages_(0), - sender_(std::bind(&big_payload_test_client::run, this)) { - switch (test_mode_) { - case big_payload_test::test_mode::RANDOM: - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_RANDOM; - break; - case big_payload_test::test_mode::LIMITED: - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_LIMITED; - break; - case big_payload_test::test_mode::LIMITED_GENERAL: - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_LIMITED_GENERAL; - break; - case big_payload_test::test_mode::QUEUE_LIMITED_GENERAL: - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_QUEUE_LIMITED_GENERAL; - break; - case big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC: - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_QUEUE_LIMITED_SPECIFIC; - break; - case big_payload_test::test_mode::UDP: - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_UDP; - break; - default: - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID; - break; - } -} - -bool big_payload_test_client::init() -{ - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - - app_->register_state_handler( - std::bind(&big_payload_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, - std::bind(&big_payload_test_client::on_message, this, - std::placeholders::_1)); - - app_->register_availability_handler(service_id_, - big_payload_test::TEST_SERVICE_INSTANCE_ID, - std::bind(&big_payload_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - return true; -} - -void big_payload_test_client::start() -{ - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void big_payload_test_client::stop() -{ - VSOMEIP_INFO << "Stopping..."; - if (test_mode_ == big_payload_test::test_mode::LIMITED - || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { - std::this_thread::sleep_for(std::chrono::milliseconds(3000)); - EXPECT_EQ(number_of_acknowledged_messages_, number_of_messages_to_send_ / 4); - } else if (test_mode_ == big_payload_test::test_mode::UDP) { - std::this_thread::sleep_for(std::chrono::milliseconds(3000)); - EXPECT_EQ(number_of_acknowledged_messages_, number_of_messages_to_send_); - } - app_->clear_all_handler(); - app_->stop(); -} - -void big_payload_test_client::join_sender_thread(){ - sender_.join(); - if (test_mode_ == big_payload_test::test_mode::LIMITED - || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { - EXPECT_EQ(number_of_acknowledged_messages_, number_of_messages_to_send_ / 4); - } else if (test_mode_ == big_payload_test::test_mode::UDP) { - EXPECT_EQ(number_of_sent_messages_, number_of_acknowledged_messages_); - } else { - EXPECT_EQ(number_of_sent_messages_, number_of_acknowledged_messages_); - } -} - -void big_payload_test_client::on_state(vsomeip::state_type_e _state) -{ - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - app_->request_service(service_id_, - big_payload_test::TEST_SERVICE_INSTANCE_ID, false); - } -} - -void big_payload_test_client::on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) -{ - VSOMEIP_INFO << "Service [" << std::setw(4) << std::setfill('0') << std::hex - << _service << "." << _instance << "] is " - << (_is_available ? "available." : "NOT available."); - - if(service_id_ == _service - && big_payload_test::TEST_SERVICE_INSTANCE_ID == _instance) - { - if(is_available_ && !_is_available) - { - is_available_ = false; - } - else if(_is_available && !is_available_) - { - is_available_ = true; - send(); - } - } -} - -void big_payload_test_client::on_message(const std::shared_ptr& _response) -{ - VSOMEIP_INFO << "Received a response from Service [" << std::setw(4) - << std::setfill('0') << std::hex << _response->get_service() << "." - << std::setw(4) << std::setfill('0') << std::hex - << _response->get_instance() << "] to Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex - << _response->get_client() << "/" << std::setw(4) - << std::setfill('0') << std::hex << _response->get_session() - << "] size: " << std::dec << _response->get_payload()->get_length(); - static vsomeip::session_t last_session(0); - ASSERT_GT(_response->get_session(), last_session); - last_session = _response->get_session(); - - if(test_mode_ == big_payload_test::test_mode::RANDOM) { - ASSERT_LT(_response->get_payload()->get_length(), big_payload_test::BIG_PAYLOAD_SIZE_RANDOM); - } else if (test_mode_ == big_payload_test::test_mode::UDP) { - EXPECT_EQ(big_payload_test::BIG_PAYLOAD_SIZE_UDP, _response->get_payload()->get_length()); - } else { - ASSERT_EQ(_response->get_payload()->get_length(), big_payload_test::BIG_PAYLOAD_SIZE); - } - - bool check(true); - vsomeip::length_t len = _response->get_payload()->get_length(); - vsomeip::byte_t* datap = _response->get_payload()->get_data(); - for(unsigned int i = 0; i < len; ++i) { - check = check && datap[i] == big_payload_test::DATA_SERVICE_TO_CLIENT; - } - if(!check) { - GTEST_FATAL_FAILURE_("wrong data transmitted"); - } - number_of_acknowledged_messages_++; - if (test_mode_ == big_payload_test::test_mode::LIMITED - || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { - if (number_of_acknowledged_messages_ == number_of_messages_to_send_ / 4) { - send(); - } - } else if ( number_of_acknowledged_messages_ == number_of_messages_to_send_) { - send(); - } -} - -void big_payload_test_client::send() -{ - std::lock_guard its_lock(mutex_); - blocked_ = true; - condition_.notify_one(); -} - -void big_payload_test_client::run() -{ - std::unique_lock its_lock(mutex_); - while (!blocked_) - { - condition_.wait(its_lock); - } - blocked_ = false; - - request_->set_service(service_id_); - request_->set_instance(big_payload_test::TEST_SERVICE_INSTANCE_ID); - request_->set_method(big_payload_test::TEST_SERVICE_METHOD_ID); - - std::srand(static_cast(std::time(0))); - - std::shared_ptr its_payload = - vsomeip::runtime::get()->create_payload(); - std::vector its_payload_data; - - for (unsigned int i = 0; i < number_of_messages_to_send_; i++) - { - if (test_mode_ == big_payload_test::test_mode::RANDOM) { - unsigned int datasize(static_cast(std::rand()) % big_payload_test::BIG_PAYLOAD_SIZE_RANDOM); - its_payload_data.assign(datasize, big_payload_test::DATA_CLIENT_TO_SERVICE); - } else if (test_mode_ == big_payload_test::test_mode::LIMITED - || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { - if (i % 2) { - // try to sent a too big payload for half of the messages - its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE + 1, - big_payload_test::DATA_CLIENT_TO_SERVICE); - } else { - its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE, - big_payload_test::DATA_CLIENT_TO_SERVICE); - } - } else if (test_mode_ == big_payload_test::test_mode::UDP) { - its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE_UDP, - big_payload_test::DATA_CLIENT_TO_SERVICE); - } else { - its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE, - big_payload_test::DATA_CLIENT_TO_SERVICE); - } - its_payload->set_data(its_payload_data); - request_->set_payload(its_payload); - app_->send(request_); - if (test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - } - VSOMEIP_INFO << "Client/Session [" << std::setw(4) << std::setfill('0') - << std::hex << request_->get_client() << "/" << std::setw(4) - << std::setfill('0') << std::hex << request_->get_session() - << "] sent a request to Service [" << std::setw(4) - << std::setfill('0') << std::hex << request_->get_service() - << "." << std::setw(4) << std::setfill('0') << std::hex - << request_->get_instance() << "] size: " << std::dec << - request_->get_payload()->get_length(); - number_of_sent_messages_++; - } - while(!blocked_) { - if (std::cv_status::timeout - == condition_.wait_for(its_lock, std::chrono::seconds(120))) { - GTEST_FATAL_FAILURE_("Didn't receive all replies within time"); - } else { - if (test_mode_ == big_payload_test::LIMITED - || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { - EXPECT_EQ(number_of_messages_to_send_ / 4, - number_of_acknowledged_messages_); - } else { - EXPECT_EQ(number_of_sent_messages_, - number_of_acknowledged_messages_); - } - } - } - stop(); -} - -static big_payload_test::test_mode test_mode(big_payload_test::test_mode::UNKNOWN); - -TEST(someip_big_payload_test, send_ten_messages_to_service) -{ - bool use_tcp = (test_mode != big_payload_test::test_mode::UDP); - big_payload_test_client test_client_(use_tcp, test_mode); - if (test_client_.init()) { - test_client_.start(); - test_client_.join_sender_thread(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if (argc > 1) { - if (std::string("RANDOM") == std::string(argv[1])) { - test_mode = big_payload_test::test_mode::RANDOM; - } else if (std::string("LIMITED") == std::string(argv[1])) { - test_mode = big_payload_test::test_mode::LIMITED; - } else if (std::string("LIMITEDGENERAL") == std::string(argv[1])) { - test_mode = big_payload_test::test_mode::LIMITED_GENERAL; - } else if (std::string("QUEUELIMITEDGENERAL") == std::string(argv[1])) { - test_mode = big_payload_test::test_mode::QUEUE_LIMITED_GENERAL; - } else if (std::string("QUEUELIMITEDSPECIFIC") == std::string(argv[1])) { - test_mode = big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC; - } else if (std::string("UDP") == std::string(argv[1])) { - test_mode = big_payload_test::test_mode::UDP; - } - } - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/big_payload_tests/big_payload_test_client.hpp b/test/big_payload_tests/big_payload_test_client.hpp deleted file mode 100644 index bb81fdc..0000000 --- a/test/big_payload_tests/big_payload_test_client.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef BIGPAYLOADTESTCLIENT_HPP_ -#define BIGPAYLOADTESTCLIENT_HPP_ - -#include - -#include - -#include -#include -#include -#include -#include - -#include "big_payload_test_globals.hpp" -#include - -class big_payload_test_client -{ -public: - big_payload_test_client(bool _use_tcp, big_payload_test::test_mode _random_mode); - bool init(); - void start(); - void stop(); - void join_sender_thread(); - void on_state(vsomeip::state_type_e _state); - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available); - void on_message(const std::shared_ptr &_response); - void send(); - void run(); - -private: - std::shared_ptr app_; - std::shared_ptr request_; - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - bool is_available_; - big_payload_test::test_mode test_mode_; - std::uint32_t number_of_messages_to_send_; - std::uint32_t number_of_sent_messages_; - std::atomic number_of_acknowledged_messages_; - std::thread sender_; - vsomeip::service_t service_id_; -}; - -#endif /* BIGPAYLOADTESTCLIENT_HPP_ */ diff --git a/test/big_payload_tests/big_payload_test_client_local_start.sh b/test/big_payload_tests/big_payload_test_client_local_start.sh deleted file mode 100755 index adbf9f4..0000000 --- a/test/big_payload_tests/big_payload_test_client_local_start.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Start the client -export VSOMEIP_APPLICATION_NAME=big_payload_test_client -export VSOMEIP_CONFIGURATION=big_payload_test_local.json -./big_payload_test_client diff --git a/test/big_payload_tests/big_payload_test_client_start.sh b/test/big_payload_tests/big_payload_test_client_start.sh deleted file mode 100755 index 5258ce8..0000000 --- a/test/big_payload_tests/big_payload_test_client_start.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Start the client -export VSOMEIP_APPLICATION_NAME=big_payload_test_client -export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client.json -./big_payload_test_client diff --git a/test/big_payload_tests/big_payload_test_external_starter.sh b/test/big_payload_tests/big_payload_test_external_starter.sh deleted file mode 100755 index 9db425d..0000000 --- a/test/big_payload_tests/big_payload_test_external_starter.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit successfully. - -if [[ $# -gt 0 && $1 != "RANDOM" && $1 != "LIMITED" && $1 != "LIMITEDGENERAL" && $1 != "QUEUELIMITEDGENERAL" && $1 != "QUEUELIMITEDSPECIFIC" && $1 != "UDP" ]] -then - echo "The only allowed parameter to this script is RANDOM or LIMITED, LIMITEDGENERAL, QUEUELIMITEDGENERAL, QUEUELIMITEDSPECIFIC or UDP" - echo "Like $0 RANDOM" - exit 1 -fi - -FAIL=0 - -# Start the client -if [[ $# -gt 0 && $1 == "RANDOM" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client_random.json -elif [[ $# -gt 0 && $1 == "LIMITEDGENERAL" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client_limited_general.json -elif [[ $# -gt 0 && $1 == "QUEUELIMITEDGENERAL" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client_queue_limited_general.json -elif [[ $# -gt 0 && $1 == "QUEUELIMITEDSPECIFIC" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client_queue_limited_specific.json -elif [[ $# -gt 0 && $1 == "UDP" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_udp_client.json -else - export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client.json -fi -./big_payload_test_client $1 & -BIG_PAYLOAD_TEST_PID=$! - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting big payload test on slave LXC" - if [[ $# -gt 0 ]]; then - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./big_payload_test_service_external_start.sh $1\"" & - else - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./big_payload_test_service_external_start.sh"' & - fi -elif [ ! -z "$USE_DOCKER" ]; then - if [[ $# -gt 0 ]]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./big_payload_test_service_external_start.sh $1" & - else - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./big_payload_test_service_external_start.sh" & - fi -elif [ ! -z "$JENKINS" ]; then - if [[ $# -gt 0 ]]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./big_payload_test_service_external_start.sh $1\" >> $WS_ROOT/slave_test_output 2>&1" & - else - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./big_payload_test_service_external_start.sh \" >> $WS_ROOT/slave_test_output 2>&1" & - fi -else -cat < - -namespace big_payload_test { - constexpr std::uint32_t BIG_PAYLOAD_SIZE = 1024*600; - constexpr std::uint32_t BIG_PAYLOAD_SIZE_UDP = 1024*30; - constexpr std::uint32_t BIG_PAYLOAD_SIZE_RANDOM = 1024*1024*10; - constexpr vsomeip::byte_t DATA_SERVICE_TO_CLIENT = 0xAA; - constexpr vsomeip::byte_t DATA_CLIENT_TO_SERVICE = 0xFF; - - constexpr std::uint32_t BIG_PAYLOAD_TEST_NUMBER_MESSAGES = 10; - constexpr std::uint32_t BIG_PAYLOAD_TEST_NUMBER_MESSAGES_RANDOM = 50; - - constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID = 0x1234; - constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_LIMITED = 0x1235; - constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_RANDOM = 0x1236; - constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_LIMITED_GENERAL = 0x1237; - constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_QUEUE_LIMITED_GENERAL = 0x1238; - constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_QUEUE_LIMITED_SPECIFIC = 0x1239; - constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_UDP = 0x1240; - - constexpr vsomeip::service_t TEST_SERVICE_INSTANCE_ID = 0x1; - constexpr vsomeip::method_t TEST_SERVICE_METHOD_ID = 0x8421; - - enum test_mode { - RANDOM, - LIMITED, - LIMITED_GENERAL, - QUEUE_LIMITED_GENERAL, - QUEUE_LIMITED_SPECIFIC, - UDP, - UNKNOWN - }; -} - -#endif /* BIG_PAYLOAD_TEST_GLOBALS_HPP_ */ diff --git a/test/big_payload_tests/big_payload_test_local.json b/test/big_payload_tests/big_payload_test_local.json deleted file mode 100644 index 983dea6..0000000 --- a/test/big_payload_tests/big_payload_test_local.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "unicast":"127.0.0.1", - "logging": - { - "level":"debug", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"big_payload_test_service", - "id":"0x1277", - "max_dispatchers" : "0" - }, - { - "name":"big_payload_test_client", - "id":"0x1344", - "max_dispatchers" : "0" - } - ], - "services": - [ - { - "service":"0x1234", - "instance":"0x5678" - } - ], - "payload-sizes": - [ - { - "unicast":"127.0.0.1", - "ports": - [ - { - "port":"30509", - "max-payload-size":"614400" - } - ] - } - ], - "routing":"big_payload_test_service", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} - diff --git a/test/big_payload_tests/big_payload_test_local_limited.json b/test/big_payload_tests/big_payload_test_local_limited.json deleted file mode 100644 index 4e8c666..0000000 --- a/test/big_payload_tests/big_payload_test_local_limited.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "unicast":"127.0.0.1", - "logging": - { - "level":"error", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"big_payload_test_service", - "id":"0x1277", - "max_dispatchers" : "0" - }, - { - "name":"big_payload_test_client", - "id":"0x1344", - "max_dispatchers" : "0" - } - ], - "services": - [ - { - "service":"0x1234", - "instance":"0x5678" - } - ], - "max-payload-size-local" : "614400", - "routing":"big_payload_test_service", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} - diff --git a/test/big_payload_tests/big_payload_test_local_queue_limited.json b/test/big_payload_tests/big_payload_test_local_queue_limited.json deleted file mode 100644 index 9700309..0000000 --- a/test/big_payload_tests/big_payload_test_local_queue_limited.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "unicast":"127.0.0.1", - "logging": - { - "level":"error", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"big_payload_test_service", - "id":"0x1277", - "max_dispatchers" : "0" - }, - { - "name":"big_payload_test_client", - "id":"0x1344", - "max_dispatchers" : "0" - } - ], - "services": - [ - { - "service":"0x1234", - "instance":"0x5678" - } - ], - "endpoint-queue-limit-local" : "614429", - "routing":"big_payload_test_service", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} - diff --git a/test/big_payload_tests/big_payload_test_local_random.json b/test/big_payload_tests/big_payload_test_local_random.json deleted file mode 100644 index 0cf2081..0000000 --- a/test/big_payload_tests/big_payload_test_local_random.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "unicast":"127.0.0.1", - "logging": - { - "level":"debug", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"big_payload_test_service", - "id":"0x1277", - "max_dispatchers" : "0" - }, - { - "name":"big_payload_test_client", - "id":"0x1344", - "max_dispatchers" : "0" - } - ], - "services": - [ - { - "service":"0x1234", - "instance":"0x5678" - } - ], - "buffer-shrink-threshold" : "2", - "routing":"big_payload_test_service", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} - diff --git a/test/big_payload_tests/big_payload_test_local_starter.sh b/test/big_payload_tests/big_payload_test_local_starter.sh deleted file mode 100755 index 6439cac..0000000 --- a/test/big_payload_tests/big_payload_test_local_starter.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit successfully. - -if [[ $# -gt 0 && $1 != "RANDOM" && $1 != "LIMITED" && $1 != "QUEUELIMITEDGENERAL" ]] -then - echo "The only allowed parameter to this script is RANDOM or LIMITED or QUEUELIMITEDGENERAL." - echo "Like $0 RANDOM" - exit 1 -fi - - -FAIL=0 - -# Start the service -if [[ $# -gt 0 && $1 == "RANDOM" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_local_random.json -elif [[ $# -gt 0 && $1 == "LIMITED" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_local_limited.json -elif [[ $# -gt 0 && $1 == "QUEUELIMITEDGENERAL" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_local_queue_limited.json -else - export VSOMEIP_CONFIGURATION=big_payload_test_local.json -fi -./big_payload_test_service $1 & - -# Start the client -./big_payload_test_client $1 & - -# Wait until client and service are finished -for job in $(jobs -p) -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if client and server both exited successfully -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/big_payload_tests/big_payload_test_service.cpp b/test/big_payload_tests/big_payload_test_service.cpp deleted file mode 100644 index ab70046..0000000 --- a/test/big_payload_tests/big_payload_test_service.cpp +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "big_payload_test_service.hpp" - -#include "big_payload_test_globals.hpp" - -big_payload_test_service::big_payload_test_service(big_payload_test::test_mode _test_mode) : - app_(vsomeip::runtime::get()->create_application("big_payload_test_service")), - is_registered_(false), - blocked_(false), - test_mode_(_test_mode), - number_of_received_messages_(0), - offer_thread_(std::bind(&big_payload_test_service::run, this)) -{ - switch (test_mode_) { - case big_payload_test::test_mode::RANDOM: - expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES_RANDOM; - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_RANDOM; - break; - case big_payload_test::test_mode::LIMITED: - expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES / 2; - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_LIMITED; - break; - case big_payload_test::test_mode::LIMITED_GENERAL: - expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES / 2; - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_LIMITED_GENERAL; - break; - case big_payload_test::test_mode::QUEUE_LIMITED_GENERAL: - expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES / 2; - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_QUEUE_LIMITED_GENERAL; - break; - case big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC: - expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES / 2; - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_QUEUE_LIMITED_SPECIFIC; - break; - case big_payload_test::test_mode::UDP: - expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES; - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_UDP; - break; - default: - expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES; - service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID; - break; - } -} - -bool big_payload_test_service::init() -{ - std::lock_guard its_lock(mutex_); - std::srand(static_cast(std::time(0))); - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - app_->register_message_handler(vsomeip::ANY_SERVICE, - big_payload_test::TEST_SERVICE_INSTANCE_ID, - big_payload_test::TEST_SERVICE_METHOD_ID, - std::bind(&big_payload_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&big_payload_test_service::on_state, this, - std::placeholders::_1)); - return true; -} - -void big_payload_test_service::start() -{ - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void big_payload_test_service::stop() -{ - VSOMEIP_INFO << "Stopping..."; - stop_offer(); - app_->clear_all_handler(); - app_->stop(); -} - -void big_payload_test_service::join_offer_thread() -{ - offer_thread_.join(); -} - -void big_payload_test_service::detach_offer_thread() -{ - offer_thread_.detach(); -} - -void big_payload_test_service::offer() { - app_->offer_service(service_id_, - big_payload_test::TEST_SERVICE_INSTANCE_ID); -} - -void big_payload_test_service::stop_offer() { - app_->stop_offer_service(service_id_, - big_payload_test::TEST_SERVICE_INSTANCE_ID); -} - -void big_payload_test_service::on_state(vsomeip::state_type_e _state) -{ - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : - "deregistered."); - - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - if(!is_registered_) - { - is_registered_ = true; - std::lock_guard its_lock(mutex_); - blocked_ = true; - // "start" the run method thread - condition_.notify_one(); - } - } - else - { - is_registered_ = false; - } -} - -void big_payload_test_service::on_message(const std::shared_ptr& _request) -{ - VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _request->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _request->get_session() << "] size: " << std::dec - << _request->get_payload()->get_length(); - { - std::lock_guard its_lock(mutex_); - incoming_requests_.push(_request); - condition_.notify_one(); - } - - -} - -void big_payload_test_service::run() -{ - { - std::unique_lock its_lock(mutex_); - while (!blocked_) { - condition_.wait(its_lock); - } - - offer(); - - // wait for shutdown - blocked_ = false; - while (!blocked_ || !incoming_requests_.empty()) { - if (incoming_requests_.empty()) { - condition_.wait(its_lock); - } - auto _request = incoming_requests_.front(); - incoming_requests_.pop(); - number_of_received_messages_++; - its_lock.unlock(); - - static vsomeip::session_t last_session(0); - ASSERT_GT(_request->get_session(), last_session); - last_session = _request->get_session(); - if (test_mode_ == big_payload_test::test_mode::RANDOM) { - EXPECT_LT(_request->get_payload()->get_length(), big_payload_test::BIG_PAYLOAD_SIZE_RANDOM); - } else if (test_mode_ == big_payload_test::test_mode::UDP) { - EXPECT_EQ(big_payload_test::BIG_PAYLOAD_SIZE_UDP, _request->get_payload()->get_length()); - } else { - EXPECT_EQ(big_payload_test::BIG_PAYLOAD_SIZE, _request->get_payload()->get_length()); - } - bool check(true); - vsomeip::length_t len = _request->get_payload()->get_length(); - vsomeip::byte_t* datap = _request->get_payload()->get_data(); - for(unsigned int i = 0; i < len; ++i) { - check = check && datap[i] == big_payload_test::DATA_CLIENT_TO_SERVICE; - } - if(!check) { - GTEST_FATAL_FAILURE_("wrong data transmitted"); - } - - // send response - std::shared_ptr its_response = - vsomeip::runtime::get()->create_response(_request); - - std::shared_ptr its_payload = vsomeip::runtime::get() - ->create_payload(); - std::vector its_payload_data; - if (test_mode_ == big_payload_test::test_mode::RANDOM) { - its_payload_data.assign(static_cast(std::rand()) % big_payload_test::BIG_PAYLOAD_SIZE_RANDOM, - big_payload_test::DATA_SERVICE_TO_CLIENT); - } else if (test_mode_ == big_payload_test::test_mode::LIMITED - || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { - if (number_of_received_messages_ % 2) { - // try to send to big response for half of the received messsages. - // this way the client will only get replies for a fourth of his sent - // requests as he tries to sent to big data for every second request - // as well - its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE + 1, - big_payload_test::DATA_SERVICE_TO_CLIENT); - } else { - its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE, - big_payload_test::DATA_SERVICE_TO_CLIENT); - } - } else if (test_mode_ == big_payload_test::test_mode::UDP) { - its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE_UDP, - big_payload_test::DATA_SERVICE_TO_CLIENT); - } else { - its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE, - big_payload_test::DATA_SERVICE_TO_CLIENT); - } - - its_payload->set_data(its_payload_data); - its_response->set_payload(its_payload); - - app_->send(its_response); - - if(number_of_received_messages_ == expected_messages_) { - ASSERT_EQ(expected_messages_, number_of_received_messages_); - blocked_ = true; - } - its_lock.lock(); - } - } - std::this_thread::sleep_for(std::chrono::seconds(3)); - if (test_mode_ == big_payload_test::test_mode::LIMITED - || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL - || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC - || test_mode_ == big_payload_test::test_mode::UDP) { - EXPECT_EQ(expected_messages_, number_of_received_messages_); - } - stop(); -} - -static big_payload_test::test_mode test_mode(big_payload_test::test_mode::UNKNOWN); - - -TEST(someip_big_payload_test, receive_ten_messages_and_send_reply) -{ - big_payload_test_service test_service(test_mode); - if (test_service.init()) { - test_service.start(); - test_service.join_offer_thread(); - } else { - test_service.detach_offer_thread(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if (argc > 1) { - if (std::string("RANDOM") == std::string(argv[1])) { - test_mode = big_payload_test::test_mode::RANDOM; - } else if (std::string("LIMITED") == std::string(argv[1])) { - test_mode = big_payload_test::test_mode::LIMITED; - } else if (std::string("LIMITEDGENERAL") == std::string(argv[1])) { - test_mode = big_payload_test::test_mode::LIMITED_GENERAL; - } else if (std::string("QUEUELIMITEDGENERAL") == std::string(argv[1])) { - test_mode = big_payload_test::test_mode::QUEUE_LIMITED_GENERAL; - } else if (std::string("QUEUELIMITEDSPECIFIC") == std::string(argv[1])) { - test_mode = big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC; - } else if (std::string("UDP") == std::string(argv[1])) { - test_mode = big_payload_test::test_mode::UDP; - } - } - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/big_payload_tests/big_payload_test_service.hpp b/test/big_payload_tests/big_payload_test_service.hpp deleted file mode 100644 index 44af28a..0000000 --- a/test/big_payload_tests/big_payload_test_service.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef BIGPAYLOADTESTSERVICE_HPP_ -#define BIGPAYLOADTESTSERVICE_HPP_ -#include - -#include - -#include -#include -#include -#include -#include - -#include "big_payload_test_globals.hpp" -#include - - -class big_payload_test_service -{ -public: - big_payload_test_service(big_payload_test::test_mode _test_mode); - bool init(); - void start(); - void stop(); - void offer(); - void stop_offer(); - void join_offer_thread(); - void detach_offer_thread(); - void on_state(vsomeip::state_type_e _state); - void on_message(const std::shared_ptr &_request); - void run(); - -private: - std::shared_ptr app_; - bool is_registered_; - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - big_payload_test::test_mode test_mode_; - std::uint32_t number_of_received_messages_; - std::thread offer_thread_; - std::uint32_t expected_messages_; - vsomeip::service_t service_id_; - std::queue> incoming_requests_; -}; - -#endif /* BIGPAYLOADTESTSERVICE_HPP_ */ diff --git a/test/big_payload_tests/big_payload_test_service_external_start.sh b/test/big_payload_tests/big_payload_test_service_external_start.sh deleted file mode 100755 index ac8dd60..0000000 --- a/test/big_payload_tests/big_payload_test_service_external_start.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -if [[ $# -gt 0 && $1 != "RANDOM" && $1 != "LIMITED" && $1 != "LIMITEDGENERAL" && $1 != "QUEUELIMITEDGENERAL" && $1 != "QUEUELIMITEDSPECIFIC" && $1 != "UDP" ]] -then - echo "The only allowed parameter to this script is RANDOM, LIMITED, LIMITEDGENERAL, QUEUELIMITEDGENERAL, QUEUELIMITEDSPECIFIC or UDP" - echo "Like $0 RANDOM" - exit 1 -fi - -# Start the service -if [[ $# -gt 0 && $1 == "RANDOM" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_tcp_service_random.json -elif [[ $# -gt 0 && $1 == "LIMITEDGENERAL" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_tcp_service_limited_general.json -elif [[ $# -gt 0 && $1 == "QUEUELIMITEDGENERAL" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_tcp_service_queue_limited_general.json -elif [[ $# -gt 0 && $1 == "QUEUELIMITEDSPECIFIC" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_tcp_service_queue_limited_specific.json -elif [[ $# -gt 0 && $1 == "UDP" ]]; then - export VSOMEIP_CONFIGURATION=big_payload_test_udp_service.json -else - export VSOMEIP_CONFIGURATION=big_payload_test_tcp_service.json -fi -./big_payload_test_service $1 diff --git a/test/big_payload_tests/big_payload_test_service_local_start.sh b/test/big_payload_tests/big_payload_test_service_local_start.sh deleted file mode 100755 index 299af82..0000000 --- a/test/big_payload_tests/big_payload_test_service_local_start.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Start the service -export VSOMEIP_APPLICATION_NAME=big_payload_test_service -export VSOMEIP_CONFIGURATION=big_payload_test_local.json -./big_payload_test_service diff --git a/test/big_payload_tests/conf/big_payload_test_tcp_client.json.in b/test/big_payload_tests/conf/big_payload_test_tcp_client.json.in deleted file mode 100644 index 0f23a10..0000000 --- a/test/big_payload_tests/conf/big_payload_test_tcp_client.json.in +++ /dev/null @@ -1,43 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "netmask":"255.255.255.0", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"true", - "path":"/var/log/vsomeip.log" - }, - "dlt":"true" - }, - "applications": - [ - { - "name":"big_payload_test_client", - "id":"0x1343" - } - ], - "payload-sizes": - [ - { - "unicast":"@TEST_IP_SLAVE@", - "ports": - [ - { - "port":"30509", - "max-payload-size":"614400" - } - ] - } - ], - "routing":"big_payload_test_client", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/big_payload_tests/conf/big_payload_test_tcp_client_limited_general.json.in b/test/big_payload_tests/conf/big_payload_test_tcp_client_limited_general.json.in deleted file mode 100644 index f28efc8..0000000 --- a/test/big_payload_tests/conf/big_payload_test_tcp_client_limited_general.json.in +++ /dev/null @@ -1,31 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "netmask":"255.255.255.0", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"true", - "path":"/var/log/vsomeip.log" - }, - "dlt":"true" - }, - "applications": - [ - { - "name":"big_payload_test_client", - "id":"0x1343" - } - ], - "max-payload-size-reliable":"614400", - "routing":"big_payload_test_client", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_general.json.in b/test/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_general.json.in deleted file mode 100644 index a193ab8..0000000 --- a/test/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_general.json.in +++ /dev/null @@ -1,31 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "netmask":"255.255.255.0", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"true", - "path":"/var/log/vsomeip.log" - }, - "dlt":"true" - }, - "applications": - [ - { - "name":"big_payload_test_client", - "id":"0x1343" - } - ], - "endpoint-queue-limit-external" : "614416", - "routing":"big_payload_test_client", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_specific.json.in b/test/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_specific.json.in deleted file mode 100644 index 79f3486..0000000 --- a/test/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_specific.json.in +++ /dev/null @@ -1,43 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "netmask":"255.255.255.0", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"true", - "path":"/var/log/vsomeip.log" - }, - "dlt":"true" - }, - "applications": - [ - { - "name":"big_payload_test_client", - "id":"0x1343" - } - ], - "endpoint-queue-limits" : - [ - { - "unicast":"@TEST_IP_SLAVE@", - "ports": - [ - { - "port":"30509", - "queue-size-limit":"614416" - } - ] - } - ], - "routing":"big_payload_test_client", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/big_payload_tests/conf/big_payload_test_tcp_client_random.json.in b/test/big_payload_tests/conf/big_payload_test_tcp_client_random.json.in deleted file mode 100644 index 85cf393..0000000 --- a/test/big_payload_tests/conf/big_payload_test_tcp_client_random.json.in +++ /dev/null @@ -1,32 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "netmask":"255.255.255.0", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"true", - "path":"/var/log/vsomeip.log" - }, - "dlt":"true" - }, - "applications": - [ - { - "name":"big_payload_test_client", - "id":"0x1343", - "max_dispatch_time" : "5000" - } - ], - "buffer-shrink-threshold" : "2", - "routing":"big_payload_test_client", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/big_payload_tests/conf/big_payload_test_tcp_service.json.in b/test/big_payload_tests/conf/big_payload_test_tcp_service.json.in deleted file mode 100644 index 08149bb..0000000 --- a/test/big_payload_tests/conf/big_payload_test_tcp_service.json.in +++ /dev/null @@ -1,81 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"debug", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"big_payload_test_service", - "id":"0x1277" - } - ], - "services": - [ - { - "service":"0x1234", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1235", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1236", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1237", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - } - ], - "payload-sizes": - [ - { - "unicast":"@TEST_IP_SLAVE@", - "ports": - [ - { - "port":"30509", - "max-payload-size":"614400" - } - ] - } - ], - "routing":"big_payload_test_service", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/big_payload_tests/conf/big_payload_test_tcp_service_limited_general.json.in b/test/big_payload_tests/conf/big_payload_test_tcp_service_limited_general.json.in deleted file mode 100644 index f8414f3..0000000 --- a/test/big_payload_tests/conf/big_payload_test_tcp_service_limited_general.json.in +++ /dev/null @@ -1,69 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"debug", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"big_payload_test_service", - "id":"0x1277" - } - ], - "services": - [ - { - "service":"0x1234", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1235", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1236", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1237", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - } - ], - "max-payload-size-reliable":"614400", - "routing":"big_payload_test_service", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_general.json.in b/test/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_general.json.in deleted file mode 100644 index ad5b28c..0000000 --- a/test/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_general.json.in +++ /dev/null @@ -1,87 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"debug", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"big_payload_test_service", - "id":"0x1277" - } - ], - "services": - [ - { - "service":"0x1234", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1235", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1236", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1237", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1238", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1239", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - } - ], - "endpoint-queue-limit-external" : "614416", - "routing":"big_payload_test_service", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_specific.json.in b/test/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_specific.json.in deleted file mode 100644 index 87bcdaa..0000000 --- a/test/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_specific.json.in +++ /dev/null @@ -1,99 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"debug", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"big_payload_test_service", - "id":"0x1277" - } - ], - "services": - [ - { - "service":"0x1234", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1235", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1236", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1237", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1238", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1239", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - } - ], - "endpoint-queue-limits" : - [ - { - "unicast":"@TEST_IP_SLAVE@", - "ports": - [ - { - "port":"30509", - "queue-size-limit":"614416" - } - ] - } - ], - "routing":"big_payload_test_service", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/big_payload_tests/conf/big_payload_test_tcp_service_random.json.in b/test/big_payload_tests/conf/big_payload_test_tcp_service_random.json.in deleted file mode 100644 index d583fd1..0000000 --- a/test/big_payload_tests/conf/big_payload_test_tcp_service_random.json.in +++ /dev/null @@ -1,70 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"debug", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"big_payload_test_service", - "id":"0x1277", - "max_dispatch_time" : "5000" - } - ], - "services": - [ - { - "service":"0x1234", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1235", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1236", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1237", - "instance":"0x01", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"false" - } - } - ], - "buffer-shrink-threshold" : "2", - "routing":"big_payload_test_service", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/big_payload_tests/conf/big_payload_test_udp_client.json.in b/test/big_payload_tests/conf/big_payload_test_udp_client.json.in deleted file mode 100644 index 5a7ee36..0000000 --- a/test/big_payload_tests/conf/big_payload_test_udp_client.json.in +++ /dev/null @@ -1,44 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "netmask":"255.255.255.0", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"true", - "path":"/var/log/vsomeip.log" - }, - "dlt":"true" - }, - "applications": - [ - { - "name":"big_payload_test_client", - "id":"0x1343", - "max_dispatchers" : "0" - } - ], - "services": - [ - { - "service":"0x1240", - "instance":"0x01", - "unicast":"@TEST_IP_SLAVE@", - "unreliable": "30509", - "someip-tp" : { - "client-to-service" : [ "0x8421" ] - } - } - ], - "max-payload-size-reliable":"614400", - "routing":"big_payload_test_client", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/big_payload_tests/conf/big_payload_test_udp_service.json.in b/test/big_payload_tests/conf/big_payload_test_udp_service.json.in deleted file mode 100644 index 7f71a05..0000000 --- a/test/big_payload_tests/conf/big_payload_test_udp_service.json.in +++ /dev/null @@ -1,41 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"debug", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"big_payload_test_service", - "id":"0x1277", - "max_dispatchers" : "0" - } - ], - "services": - [ - { - "service":"0x1240", - "instance":"0x01", - "unreliable": "30509", - "someip-tp" : { - "service-to-client" : [ "0x8421" ] - } - } - ], - "routing":"big_payload_test_service", - "service-discovery": - { - "enable":"true", - "multicast":"224.244.224.245", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/client_id_tests/client_id_test_globals.hpp b/test/client_id_tests/client_id_test_globals.hpp deleted file mode 100644 index e4b2cb8..0000000 --- a/test/client_id_tests/client_id_test_globals.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef CLIENT_ID_TEST_CLIENT_ID_TEST_GLOBALS_HPP_ -#define CLIENT_ID_TEST_CLIENT_ID_TEST_GLOBALS_HPP_ - -namespace client_id_test { - -struct service_info { - vsomeip::service_t service_id; - vsomeip::instance_t instance_id; - vsomeip::method_t method_id; - vsomeip::client_t offering_client; -}; - -static constexpr std::array service_infos = {{ - // placeholder to be consistent w/ client ids, service ids, app names - { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }, - // node 1 - { 0x1000, 0x1, 0x1111, 0x1111 }, - { 0x2000, 0x1, 0x2222, 0x2222}, - { 0x3000, 0x1, 0x3333, 0x3333}, - // node 2 - { 0x4000, 0x1, 0x4444, 0x4444 }, - { 0x5000, 0x1, 0x5555, 0x5555 }, - { 0x6000, 0x1, 0x6666, 0x6666 } -}}; - -static constexpr int messages_to_send = 10; -} - -#endif /* CLIENT_ID_TEST_CLIENT_ID_TEST_GLOBALS_HPP_ */ diff --git a/test/client_id_tests/client_id_test_master_starter.sh b/test/client_id_tests/client_id_test_master_starter.sh deleted file mode 100755 index 1351fb1..0000000 --- a/test/client_id_tests/client_id_test_master_starter.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 1 ] -then - echo "Please pass a json file to this script." - echo "For example: $0 client_id_test_diff_client_ids_diff_ports_master.json" - exit 1 -fi - -MASTER_JSON_FILE=$1 -CLIENT_JSON_FILE=${MASTER_JSON_FILE/master/slave} - -FAIL=0 - -# Start the services -export VSOMEIP_APPLICATION_NAME=client_id_test_service_one -export VSOMEIP_CONFIGURATION=$1 -./client_id_test_service 1 & -CLIENT_ID_PIDS[1]=$! - -export VSOMEIP_APPLICATION_NAME=client_id_test_service_two -export VSOMEIP_CONFIGURATION=$1 -./client_id_test_service 2 & -CLIENT_ID_PIDS[2]=$! - -export VSOMEIP_APPLICATION_NAME=client_id_test_service_three -export VSOMEIP_CONFIGURATION=$1 -./client_id_test_service 3 & -CLIENT_ID_PIDS[3]=$! - -sleep 1 - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting client id test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./client_id_test_slave_starter.sh $CLIENT_JSON_FILE\"" & -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./client_id_test_slave_starter.sh $CLIENT_JSON_FILE" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./client_id_test_slave_starter.sh $CLIENT_JSON_FILE\" >> $WS_ROOT/slave_test_output 2>&1" & - -else -cat < -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "client_id_test_globals.hpp" - - -class client_id_test_service { -public: - client_id_test_service(struct client_id_test::service_info _service_info) : - service_info_(_service_info), - app_(vsomeip::runtime::get()->create_application()), - blocked_(false), - offer_thread_(std::bind(&client_id_test_service::run, this)), - stopped_(false), - stop_thread_(std::bind(&client_id_test_service::wait_for_stop, this)) { - if (!app_->init()) { - offer_thread_.detach(); - stop_thread_.detach(); - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&client_id_test_service::on_state, this, - std::placeholders::_1)); - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.method_id, - std::bind(&client_id_test_service::on_request, this, - std::placeholders::_1)); - app_->register_message_handler(vsomeip::ANY_SERVICE, - service_info_.instance_id, vsomeip::ANY_METHOD, - std::bind(&client_id_test_service::on_response, this, - std::placeholders::_1)); - - for(const auto& i : client_id_test::service_infos) { - if ((i.service_id == service_info_.service_id - && i.instance_id == service_info_.instance_id) - || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { - continue; - } - app_->request_service(i.service_id, i.instance_id); - app_->register_availability_handler(i.service_id, i.instance_id, - std::bind(&client_id_test_service::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - - other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; - other_services_received_response_[std::make_pair(i.service_id, i.method_id)] = 0; - other_services_received_request_[i.offering_client] = 0; - } - - app_->start(); - } - - ~client_id_test_service() { - if (offer_thread_.joinable()) { - offer_thread_.join(); - } - if (stop_thread_.joinable()) { - stop_thread_.join(); - } - } - - void offer() { - app_->offer_service(service_info_.service_id, service_info_.instance_id); - } - - void stop_offer() { - app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - blocked_ = true; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - if(_is_available) { - VSOMEIP_INFO - << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Service [" - << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance - << "] is " - << (_is_available ? "available." : "NOT available."); - - auto its_service = other_services_available_.find(std::make_pair(_service, _instance)); - if(its_service != other_services_available_.end()) { - its_service->second = true; - } - - if(std::all_of(other_services_available_.cbegin(), - other_services_available_.cend(), - [](const std::map, bool>::value_type& v) { - return v.second;})) { - std::lock_guard its_lock(mutex_); - blocked_ = true; - condition_.notify_one(); - } - } - } - - void on_request(const std::shared_ptr &_message) { - if(_message->get_message_type() == vsomeip::message_type_e::MT_REQUEST) { - VSOMEIP_DEBUG - << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id - << "] Received a request with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_session() << "]"; - std::shared_ptr its_response = vsomeip::runtime::get() - ->create_response(_message); - app_->send(its_response); - - other_services_received_request_[_message->get_client()]++; - if(all_responses_and_requests_received()) { - std::lock_guard its_lock(stop_mutex_); - stopped_ = true; - stop_condition_.notify_one(); - } - } - } - - void on_response(const std::shared_ptr &_message) { - if(_message->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - VSOMEIP_DEBUG - << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id - << "] Received a response with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_session() << "] from Service/Method [" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_service() << "/" << std::setw(4) << std::setfill('0') - << std::hex << _message->get_method() <<"]"; - other_services_received_response_[std::make_pair(_message->get_service(), - _message->get_method())]++; - - if(all_responses_and_requests_received()) { - std::lock_guard its_lock(stop_mutex_); - stopped_ = true; - stop_condition_.notify_one(); - } - } - } - - bool all_responses_and_requests_received() { - const bool responses = std::all_of( - other_services_received_response_.cbegin(), - other_services_received_response_.cend(), - [](const std::map, std::uint32_t>::value_type& v) - { return v.second == client_id_test::messages_to_send;}); - const bool requests = std::all_of( - other_services_received_request_.cbegin(), - other_services_received_request_.cend(), - [](const std::map::value_type& v) - { return v.second == client_id_test::messages_to_send;}); - return (responses && requests); - } - - void run() { - std::unique_lock its_lock(mutex_); - while (!blocked_) { - condition_.wait(its_lock); - } - blocked_ = false; - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - - - while (!blocked_) { - condition_.wait(its_lock); - } - blocked_ = false; - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Sending"; - // send a message to all other services - for (int var = 0; var < client_id_test::messages_to_send; ++var) { - for(const client_id_test::service_info& i: client_id_test::service_infos) { - if ((i.service_id == service_info_.service_id - && i.instance_id == service_info_.instance_id) - || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { - continue; - } - std::shared_ptr msg = vsomeip::runtime::get()->create_request(); - msg->set_service(i.service_id); - msg->set_instance(i.instance_id); - msg->set_method(i.method_id); - app_->send(msg); - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') - << std::hex << service_info_.service_id - << "] Sending a request to Service/Method [" - << std::setw(4) << std::setfill('0') << std::hex - << i.service_id << "/" << std::setw(4) << std::setfill('0') - << std::hex << i.instance_id <<"]"; - } - } - - while (!blocked_) { - condition_.wait(its_lock); - } - blocked_ = false; - } - - void wait_for_stop() { - std::unique_lock its_lock(stop_mutex_); - while (!stopped_) { - stop_condition_.wait(its_lock); - } - VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id - << "] Received responses and requests from all other services, going down"; - - // let offer thread exit - { - std::lock_guard its_lock(mutex_); - blocked_ = true; - condition_.notify_one(); - } - - std::this_thread::sleep_for(std::chrono::seconds(3)); - app_->clear_all_handler(); - app_->stop(); - } - -private: - client_id_test::service_info service_info_; - std::shared_ptr app_; - std::map, bool> other_services_available_; - std::map, std::uint32_t> other_services_received_response_; - std::map other_services_received_request_; - - bool blocked_; - std::mutex mutex_; - std::condition_variable condition_; - std::thread offer_thread_; - - bool stopped_; - std::mutex stop_mutex_; - std::condition_variable stop_condition_; - std::thread stop_thread_; -}; - -static int service_number; - -TEST(someip_client_id_test, send_ten_messages_to_service) -{ - client_id_test_service its_sample( - client_id_test::service_infos[static_cast(service_number)]); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if(argc < 2) { - std::cerr << "Please specify a service number, like: " << argv[0] << " 2" << std::endl; - std::cerr << "Valid service numbers are in the range of [1,6]" << std::endl; - return 1; - } - service_number = std::stoi(std::string(argv[1]), nullptr); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/client_id_tests/client_id_test_slave_starter.sh b/test/client_id_tests/client_id_test_slave_starter.sh deleted file mode 100755 index 4553521..0000000 --- a/test/client_id_tests/client_id_test_slave_starter.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 1 ] -then - echo "Please pass a json file to this script." - echo "For example: $0 client_id_test_diff_client_ids_diff_ports_slave.json" - exit 1 -fi - -FAIL=0 - -# Start the services -export VSOMEIP_APPLICATION_NAME=client_id_test_service_four -export VSOMEIP_CONFIGURATION=$1 -./client_id_test_service 4 & - -export VSOMEIP_APPLICATION_NAME=client_id_test_service_five -export VSOMEIP_CONFIGURATION=$1 -./client_id_test_service 5 & - -export VSOMEIP_APPLICATION_NAME=client_id_test_service_six -export VSOMEIP_CONFIGURATION=$1 -./client_id_test_service 6 & - - -# Wait until all applications are finished -for job in $(jobs -p) -do - # Fail gets incremented if one of the binaries exits - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if both exited successfully -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/client_id_tests/client_id_test_utility.cpp b/test/client_id_tests/client_id_test_utility.cpp deleted file mode 100644 index 9cfe5ab..0000000 --- a/test/client_id_tests/client_id_test_utility.cpp +++ /dev/null @@ -1,608 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include - -#include -#include -#include - -#include -#include "../../implementation/utility/include/utility.hpp" -#include "../../implementation/configuration/include/configuration.hpp" -#include "../../implementation/configuration/include/configuration_plugin.hpp" -#include "../../implementation/plugin/include/plugin_manager_impl.hpp" - -using namespace vsomeip; - -static const std::string APPLICATION_NAME_ROUTING_MANAGER = "routingmanagerd"; - -static const std::string APPLICATION_NAME_NOT_PREDEFINED = "test-application-name"; - -vsomeip::client_t CLIENT_ID_ROUTING_MANAGER = 0xFFFF; - -static const std::string APPLICATION_IN_NAME = "client_id_test_utility_service_in"; -static vsomeip::client_t APPLICATION_IN_CLIENT_ID = 0xFFFF; - -static const std::string APPLICATION_IN_NAME_TWO = "client_id_test_utility_service_in_two"; -static vsomeip::client_t APPLICATION_IN_CLIENT_ID_TWO = 0xFFFF; - -static const std::string APPLICATION_OUT_LOW_NAME = "client_id_test_utility_service_out_low"; -static const vsomeip::client_t APPLICATION_OUT_LOW_CLIENT_ID = 0x5911; - -static const std::string APPLICATION_OUT_HIGH_NAME = "client_id_test_utility_service_out_high"; -static const vsomeip::client_t APPLICATION_OUT_HIGH_CLIENT_ID = 0x7411; - -class client_id_utility_test: public ::testing::Test { -public: - client_id_utility_test() : - client_id_routing_manager_(0x0), - diagnosis_(0x0), - diagnosis_mask_(0xFF00), - client_id_base_(0x0) { - - std::shared_ptr its_configuration; - auto its_plugin = vsomeip::plugin_manager::get()->get_plugin( - vsomeip::plugin_type_e::CONFIGURATION_PLUGIN, VSOMEIP_CFG_LIBRARY); - if (its_plugin) { - auto its_config_plugin = std::dynamic_pointer_cast(its_plugin); - if (its_config_plugin) { - configuration_ = its_config_plugin->get_configuration(APPLICATION_NAME_ROUTING_MANAGER); - } - } - } -protected: - virtual void SetUp() { - ASSERT_TRUE(static_cast(configuration_)); - configuration_->load(APPLICATION_NAME_ROUTING_MANAGER); - diagnosis_mask_ = configuration_->get_diagnosis_mask(); - diagnosis_ = configuration_->get_diagnosis_address(); - - // calculate all client IDs based on mask - client_id_base_ = static_cast(diagnosis_ << 8); - CLIENT_ID_ROUTING_MANAGER = - static_cast((configuration_->get_diagnosis_address() - << 8) & configuration_->get_diagnosis_mask()); - APPLICATION_IN_CLIENT_ID = static_cast(client_id_base_ | 0x11); - APPLICATION_IN_CLIENT_ID_TWO = static_cast(client_id_base_ | 0x12); - - app_ = vsomeip::runtime::get()->create_application(APPLICATION_NAME_ROUTING_MANAGER); - EXPECT_TRUE(app_->init()); - EXPECT_EQ(CLIENT_ID_ROUTING_MANAGER, app_->get_client()); - - rm_impl_thread_ = std::thread([&](){ - app_->start(); - }); - // ensure clean preconditions - utility::reset_client_ids(); - - // required as there are two static versions of the utility class in this - // test, one in the test itself and one in libvsomeip... - client_id_routing_manager_ = utility::request_client_id( - configuration_, APPLICATION_NAME_ROUTING_MANAGER, static_cast( - (configuration_->get_diagnosis_address() << 8) - & configuration_->get_diagnosis_mask())); - EXPECT_EQ(CLIENT_ID_ROUTING_MANAGER, client_id_routing_manager_); - } - - virtual void TearDown() { - app_->stop(); - if (rm_impl_thread_.joinable()) { - rm_impl_thread_.join(); - } - app_.reset(); - utility::release_client_id(client_id_routing_manager_); - } - -protected: - std::shared_ptr configuration_; - vsomeip::client_t client_id_routing_manager_; - std::uint16_t diagnosis_; - std::uint16_t diagnosis_mask_; - client_t client_id_base_; - std::shared_ptr app_; - std::thread rm_impl_thread_; -}; - -class app_wrapper { -public: - app_wrapper(const std::string& _name) : - app_(vsomeip::runtime::get()->create_application(_name)), - client_(VSOMEIP_CLIENT_UNSET) { - EXPECT_TRUE(app_->init()); - app_->register_state_handler( - std::bind(&app_wrapper::on_state, this, std::placeholders::_1)); - app_thread_ = std::thread([&](){ app_->start(); }); - } - - ~app_wrapper() { - app_->stop(); - if (app_thread_.joinable()) { - app_thread_.join(); - } - app_.reset(); - } - - void on_state(const vsomeip::state_type_e& _state) { - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - client_ = app_->get_client(); - registered_.set_value(); - } - }; - - client_t get_client() { - if (std::future_status::timeout - == registered_.get_future().wait_for( - std::chrono::seconds(11))) { - ADD_FAILURE()<< __LINE__ << " application wasn't registered within time"; - } - return client_; - } - - std::shared_ptr get_app() { - return app_; - } - -private: - std::shared_ptr app_; - std::promise registered_; - std::thread app_thread_; - vsomeip::client_t client_; -}; - -TEST_F(client_id_utility_test, request_release_client_id) { - app_wrapper app(APPLICATION_NAME_NOT_PREDEFINED); - EXPECT_EQ(client_id_base_ | 0x1, app.get_client()); -} - -TEST_F(client_id_utility_test, request_client_id_twice) { - app_wrapper app(APPLICATION_NAME_NOT_PREDEFINED); - EXPECT_EQ(client_id_base_ | 0x1, app.get_client()); - - app_wrapper app2(APPLICATION_NAME_NOT_PREDEFINED); - EXPECT_EQ(client_id_base_ | 0x2, app2.get_client()); -} - -TEST_F(client_id_utility_test, ensure_sequential_ascending_client_id_allocation) { - app_wrapper app(APPLICATION_NAME_NOT_PREDEFINED); - EXPECT_EQ(client_id_base_ | 0x1, app.get_client()); - - auto app2 = std::make_shared(APPLICATION_NAME_NOT_PREDEFINED); - client_t app2_client = app2->get_client(); - EXPECT_EQ(client_id_base_ | 0x2, app2_client); - - app2.reset(); - - auto app3 = std::make_shared(APPLICATION_NAME_NOT_PREDEFINED); - client_t app3_client = app3->get_client(); - EXPECT_EQ(client_id_base_ | 0x3, app3_client); - - EXPECT_GT(app3_client, app2_client); - -} - -TEST_F(client_id_utility_test, ensure_preconfigured_client_ids_not_used_for_autoconfig) -{ - // request client ids until 10 over the preconfigured one - const std::uint16_t limit = - static_cast((APPLICATION_IN_CLIENT_ID - & ~diagnosis_mask_) + std::uint16_t(10)); - - std::vector> its_apps; - its_apps.reserve(limit); - - for (int i = 0; i < limit; i++ ) { - its_apps.emplace_back( - std::make_shared(APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i))); - } - for (const auto& a : its_apps) { - EXPECT_NE(APPLICATION_IN_CLIENT_ID, a->get_client()); - } - its_apps.clear(); -} - -TEST_F(client_id_utility_test, - request_predefined_client_id_in_diagnosis_range) { - auto app1 = std::make_shared(APPLICATION_IN_NAME); - EXPECT_EQ(APPLICATION_IN_CLIENT_ID, app1->get_client()); -} - -TEST_F(client_id_utility_test, - request_predefined_client_id_in_diagnosis_range_twice) { - auto app1 = std::make_shared(APPLICATION_IN_NAME); - EXPECT_EQ(APPLICATION_IN_CLIENT_ID, app1->get_client()); - - // preconfigured is already taken -> autogenerated ID should be returned - auto app2 = std::make_shared(APPLICATION_IN_NAME); - EXPECT_EQ(client_id_base_ | 0x1, app2->get_client()); -} - -TEST_F(client_id_utility_test, - request_predefined_client_id_outside_diagnosis_range_high) { - auto app1 = std::make_shared(APPLICATION_OUT_HIGH_NAME); - // we should get the client ID defined in the json file - EXPECT_EQ(APPLICATION_OUT_HIGH_CLIENT_ID, app1->get_client()); -} - -TEST_F(client_id_utility_test, - request_client_id_with_predefined_app_name_outside_diagnosis_range_high_multiple) { - - auto app1 = std::make_shared(APPLICATION_OUT_HIGH_NAME); - // we should get the client ID defined in the json file - EXPECT_EQ(APPLICATION_OUT_HIGH_CLIENT_ID, app1->get_client()); - - // preconfigured is already taken -> autogenerated ID should be returned - auto app2 = std::make_shared(APPLICATION_OUT_HIGH_NAME); - EXPECT_EQ(client_id_base_ | 0x1, app2->get_client()); - - auto app3 = std::make_shared(APPLICATION_OUT_HIGH_NAME); - EXPECT_EQ(client_id_base_ | 0x2, app3->get_client()); -} - -TEST_F(client_id_utility_test, - request_predefined_client_id_outside_diagnosis_range_low) { - auto app1 = std::make_shared(APPLICATION_OUT_LOW_NAME); - // we should get the client ID defined in the json file - EXPECT_EQ(APPLICATION_OUT_LOW_CLIENT_ID, app1->get_client()); -} - -TEST_F(client_id_utility_test, - request_predefined_client_id_outside_diagnosis_range_low_multiple) { - auto app1 = std::make_shared(APPLICATION_OUT_LOW_NAME); - // we should get the client ID defined in the json file - EXPECT_EQ(APPLICATION_OUT_LOW_CLIENT_ID, app1->get_client()); - - // preconfigured is already taken -> autogenerated ID should be returned - auto app2 = std::make_shared(APPLICATION_OUT_LOW_NAME); - EXPECT_EQ(client_id_base_ | 0x1, app2->get_client()); - - auto app3 = std::make_shared(APPLICATION_OUT_LOW_NAME); - EXPECT_EQ(client_id_base_ | 0x2, app3->get_client()); -} - -TEST_F(client_id_utility_test, - ensure_preconfigured_client_ids_in_diagnosis_range_dont_influence_autoconfig_client_ids) -{ - auto app0 = std::make_shared(APPLICATION_NAME_NOT_PREDEFINED); - EXPECT_EQ(client_id_base_ | 0x1, app0->get_client()); - - auto app1 = std::make_shared(APPLICATION_IN_NAME); - EXPECT_EQ(APPLICATION_IN_CLIENT_ID, app1->get_client()); - - auto app2 = std::make_shared(APPLICATION_IN_NAME_TWO); - EXPECT_EQ(APPLICATION_IN_CLIENT_ID_TWO, app2->get_client()); - - auto app3 = std::make_shared(APPLICATION_NAME_NOT_PREDEFINED); - EXPECT_EQ(client_id_base_ | 0x2, app3->get_client()); - - auto app4 = std::make_shared(APPLICATION_NAME_NOT_PREDEFINED); - EXPECT_EQ(client_id_base_ | 0x3, app4->get_client()); -} - -TEST_F(client_id_utility_test, exhaust_client_id_range_sequential) { - std::vector its_clients; - std::uint16_t its_max_clients(0); - for (int var = 0; var < __builtin_popcount(static_cast(~diagnosis_mask_)); ++var) { - its_max_clients = static_cast(its_max_clients | (1 << var)); - } - // -2 as two predefined client IDs are present in the json file which - // aren't assigned via autoconfiguration - const std::uint16_t max_allowed_clients = static_cast(its_max_clients - 2u); - - // acquire maximum amount of client IDs - for (int var = 0; var < 2; ++var) { - for (std::uint16_t i = 0; i < max_allowed_clients; i++) { - const vsomeip::client_t its_client = - vsomeip::utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i), - VSOMEIP_CLIENT_UNSET); - if (its_client != VSOMEIP_CLIENT_UNSET) { - if (i > 0) { - EXPECT_LT(its_clients.back(), its_client); - } - its_clients.push_back(its_client); - } else { - ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " - << static_cast(i); - } - } - // check limit is reached - EXPECT_EQ(VSOMEIP_CLIENT_UNSET, vsomeip::utility::request_client_id( - configuration_, APPLICATION_NAME_NOT_PREDEFINED + "max", - VSOMEIP_CLIENT_UNSET)); - for (const auto& c : its_clients) { - utility::release_client_id(c); - } - } - } - -TEST_F(client_id_utility_test, exhaust_client_id_range_fragmented) { - std::vector its_clients; - - // -2 as two predefined client IDs are present in the json file which - // aren't assigned via autoconfiguration - std::uint16_t its_max_clients(0); - for (int var = 0; var < __builtin_popcount(static_cast(~diagnosis_mask_)); ++var) { - its_max_clients = static_cast(its_max_clients | (1 << var)); - } - const std::uint16_t max_allowed_clients = static_cast(its_max_clients - 2u); - - for (int var = 0; var < 2; ++var) { - // acquire maximum amount of client IDs - for (std::uint16_t i = 0; i < max_allowed_clients; i++) { - const vsomeip::client_t its_client = - vsomeip::utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i), - VSOMEIP_CLIENT_UNSET); - if (its_client != VSOMEIP_CLIENT_UNSET) { - if ((var == 0 && i > 0) || - (var == 1 && i > 1) // special case as in the 1st run the last assigned client ID was 63fe - // due to the releases. In the 2nd run the first client ID therefore will be 63ff - ) { - EXPECT_LT(its_clients.back(), its_client); - } - its_clients.push_back(its_client); - } else { - ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " - << static_cast(i); - } - } - - // check limit is reached - EXPECT_EQ(VSOMEIP_CLIENT_UNSET, vsomeip::utility::request_client_id( - configuration_, APPLICATION_NAME_NOT_PREDEFINED + "max", - VSOMEIP_CLIENT_UNSET)); - - // release every second requested client ID - std::vector its_released_client_ids; - for (size_t i = 0; i < its_clients.size(); i++ ) { - if (i % 2) { - its_released_client_ids.push_back(its_clients[i]); - utility::release_client_id(its_clients[i]); - } - } - for (const client_t c : its_released_client_ids) { - for (auto it = its_clients.begin(); it != its_clients.end(); ) { - if (*it == c) { - it = its_clients.erase(it); - } else { - ++it; - } - } - } - - // acquire client IDs up to the maximum allowed amount again - for (std::uint16_t i = 0; i < its_released_client_ids.size(); i++) { - const vsomeip::client_t its_client = - vsomeip::utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i), - VSOMEIP_CLIENT_UNSET); - if (its_client != VSOMEIP_CLIENT_UNSET) { - if (i > 0) { - EXPECT_LT(its_clients.back(), its_client); - } - its_clients.push_back(its_client); - } else { - ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " - << static_cast(i); - } - } - - // check limit is reached - EXPECT_EQ(VSOMEIP_CLIENT_UNSET, vsomeip::utility::request_client_id( - configuration_, APPLICATION_NAME_NOT_PREDEFINED + "max2", - VSOMEIP_CLIENT_UNSET)); - - // release all - for (const auto& c : its_clients) { - utility::release_client_id(c); - } - its_clients.clear(); - } -} - -/* - * @test Check that the autoconfigured client IDs continue to increase even if - * some client IDs at the beginning of the range are already released again - */ -TEST_F(client_id_utility_test, exhaust_client_id_range_fragmented_extended) { - std::vector its_client_ids; - - // -1 for the routing manager, -2 as two predefined client IDs are present - // in the json file which aren't assigned via autoconfiguration - std::uint16_t its_max_clients(0); - for (int var = 0; var < __builtin_popcount(static_cast(~diagnosis_mask_)); ++var) { - its_max_clients = static_cast(its_max_clients | (1 << var)); - } - const std::uint16_t its_diagnosis_mask = configuration_->get_diagnosis_mask(); - const std::uint16_t its_client_mask = static_cast(~its_diagnosis_mask); - const client_t its_masked_diagnosis_address = static_cast( - (configuration_->get_diagnosis_address() << 8) & its_diagnosis_mask); - const client_t its_biggest_client = its_masked_diagnosis_address | its_client_mask; - - const std::uint16_t max_possible_clients = its_max_clients; - const std::uint16_t intermediate_release = 3; - const std::uint16_t max_allowed_clients = static_cast(max_possible_clients - 2u); - - // acquire (almost) maximum amount of client IDs - for (std::uint16_t i = 0; i < max_allowed_clients - intermediate_release; i++) { - client_t its_client_id = utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i), - VSOMEIP_CLIENT_UNSET); - EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); - if (its_client_id != VSOMEIP_CLIENT_UNSET) { - if (i > 0) { - EXPECT_LT(its_client_ids.back(), its_client_id); - } - its_client_ids.push_back(its_client_id); - } else { - ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " - << static_cast(i); - } - } - - // release the first intermediate_release client IDs again - std::vector its_intermediate_released_client_ids; - for (size_t i = 0; i < intermediate_release; i++ ) { - its_intermediate_released_client_ids.push_back(its_client_ids[i]); - utility::release_client_id(its_client_ids[i]); - its_client_ids.erase(its_client_ids.begin() + i); - } - - // acquire some more client IDs, these should be bigger than the already acquired - for (std::uint16_t i = 0; i < intermediate_release; i++) { - client_t its_client_id = utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i) - + "intermediate", - VSOMEIP_CLIENT_UNSET); - EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); - if (its_client_id != VSOMEIP_CLIENT_UNSET) { - EXPECT_LT(its_client_ids.back(), its_client_id); - its_client_ids.push_back(its_client_id); - } else { - ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " - << static_cast(i); - } - } - - // check correct wrap around of client IDs - for (std::uint16_t i = 0; i < intermediate_release; i++) { - client_t its_client_id = utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i), - VSOMEIP_CLIENT_UNSET); - EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); - if (its_client_id != VSOMEIP_CLIENT_UNSET) { - if (i == 0) { - EXPECT_GT(its_client_ids.back(), its_client_id); - } else { - EXPECT_LT(its_client_ids.back(), its_client_id); - } - its_client_ids.push_back(its_client_id); - } else { - ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " - << static_cast(i); - } - } - - // check limit is reached - client_t its_illegal_client_id = utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); - EXPECT_EQ(VSOMEIP_CLIENT_UNSET, its_illegal_client_id); - - // release every second requested client ID - std::vector its_released_client_ids; - for (size_t i = 0; i < its_client_ids.size(); i++ ) { - if (i % 2) { - its_released_client_ids.push_back(its_client_ids[i]); - utility::release_client_id(its_client_ids[i]); - } - } - for (const client_t c : its_released_client_ids) { - for (auto it = its_client_ids.begin(); it != its_client_ids.end(); ) { - if (*it == c) { - it = its_client_ids.erase(it); - } else { - ++it; - } - } - } - - // acquire client IDs up to the maximum allowed amount again - for (std::uint16_t i = 0; i < its_released_client_ids.size(); i++) { - client_t its_client_id = utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i), - VSOMEIP_CLIENT_UNSET); - EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); - if (its_client_id != VSOMEIP_CLIENT_UNSET) { - if (i > 0 && its_client_ids.back() != its_biggest_client) { - EXPECT_LT(its_client_ids.back(), its_client_id); - } - its_client_ids.push_back(its_client_id); - } else { - ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " - << static_cast(i); - } - } - - // check limit is reached - its_illegal_client_id = 0xFFFF; - its_illegal_client_id = utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); - EXPECT_EQ(VSOMEIP_CLIENT_UNSET, its_illegal_client_id); - - // release all - for (const client_t c : its_client_ids) { - utility::release_client_id(c); - } -} - -TEST_F(client_id_utility_test, request_released_client_id_after_maximum_client_id_is_assigned) { - std::vector its_client_ids; - std::uint16_t its_max_clients(0); - for (int var = 0; var < __builtin_popcount(static_cast(~diagnosis_mask_)); ++var) { - its_max_clients = static_cast(its_max_clients | (1 << var)); - } - const std::uint16_t max_possible_clients = its_max_clients; - // -1 for the routing manager, -2 as two predefined client IDs are present - // in the json file which aren't assigned via autoconfiguration - const std::uint16_t max_allowed_clients = static_cast(max_possible_clients - 2u); - - // acquire (almost) maximum amount of client IDs - for (std::uint16_t i = 0; i < max_allowed_clients - 1; i++) { - client_t its_client_id = utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); - EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); - if (its_client_id != VSOMEIP_CLIENT_UNSET) { - if (i > 0) { - EXPECT_LT(its_client_ids.back(), its_client_id); - } - its_client_ids.push_back(its_client_id); - } else { - ADD_FAILURE()<< "Received VSOMEIP_CLIENT_UNSET " - << static_cast(i); - } - } - - // release a client ID - utility::release_client_id(its_client_ids[10]); - - // requesting an ID should return the maximum possible ID - client_t its_max_client_id = utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); - EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_max_client_id); - its_client_ids.push_back(its_max_client_id); - - // requesting an ID should work as we have released one before - client_t its_client_id = utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); - EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); - its_client_ids.push_back(its_client_id); - - // requesting an ID should not work as all IDs are in use now - client_t its_illegal_client_id = utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); - EXPECT_EQ(VSOMEIP_CLIENT_UNSET, its_illegal_client_id); - - // release another ID - utility::release_client_id(its_client_ids[5]); - - its_client_id = utility::request_client_id(configuration_, - APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); - EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); - its_client_ids.push_back(its_client_id); - - // release all - for (const client_t c : its_client_ids) { - utility::release_client_id(c); - } - its_client_ids.clear(); -} - -#ifndef _WIN32 -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/client_id_tests/client_id_test_utility.json b/test/client_id_tests/client_id_test_utility.json deleted file mode 100644 index e07eb9a..0000000 --- a/test/client_id_tests/client_id_test_utility.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "unicast":"127.0.0.1", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "diagnosis":"0x63", - "applications": - [ - { - "name":"client_id_test_utility_service_in", - "id":"0x6311" - }, - { - "name":"client_id_test_utility_service_in_two", - "id":"0x6312" - }, - { - "name":"client_id_test_utility_service_out_low", - "id":"0x5911" - }, - { - "name":"client_id_test_utility_service_out_high", - "id":"0x7411" - } - ], - "routing":"routingmanagerd" -} diff --git a/test/client_id_tests/client_id_test_utility_discontinuous_masked_511.json b/test/client_id_tests/client_id_test_utility_discontinuous_masked_511.json deleted file mode 100644 index af3dfd6..0000000 --- a/test/client_id_tests/client_id_test_utility_discontinuous_masked_511.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "unicast":"127.0.0.1", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "diagnosis":"0x63", - "diagnosis_mask":"0xFB00", - "applications": - [ - { - "name":"client_id_test_utility_service_in", - "id":"0x6311" - }, - { - "name":"client_id_test_utility_service_in_two", - "id":"0x6312" - }, - { - "name":"client_id_test_utility_service_out_low", - "id":"0x5911" - }, - { - "name":"client_id_test_utility_service_out_high", - "id":"0x7411" - } - ], - "routing":"routingmanagerd" -} diff --git a/test/client_id_tests/client_id_test_utility_masked_127.json b/test/client_id_tests/client_id_test_utility_masked_127.json deleted file mode 100644 index 8aa5135..0000000 --- a/test/client_id_tests/client_id_test_utility_masked_127.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "unicast":"127.0.0.1", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "diagnosis":"0x63", - "diagnosis_mask":"0xFF80", - "applications": - [ - { - "name":"client_id_test_utility_service_in", - "id":"0x6311" - }, - { - "name":"client_id_test_utility_service_in_two", - "id":"0x6312" - }, - { - "name":"client_id_test_utility_service_out_low", - "id":"0x5911" - }, - { - "name":"client_id_test_utility_service_out_high", - "id":"0x7411" - } - ], - "routing":"routingmanagerd" -} diff --git a/test/client_id_tests/client_id_test_utility_masked_4095.json b/test/client_id_tests/client_id_test_utility_masked_4095.json deleted file mode 100644 index 8604435..0000000 --- a/test/client_id_tests/client_id_test_utility_masked_4095.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "unicast":"127.0.0.1", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "diagnosis":"0x60", - "diagnosis_mask":"0xF000", - "applications": - [ - { - "name":"client_id_test_utility_service_in", - "id":"0x6011" - }, - { - "name":"client_id_test_utility_service_in_two", - "id":"0x6012" - }, - { - "name":"client_id_test_utility_service_out_low", - "id":"0x5911" - }, - { - "name":"client_id_test_utility_service_out_high", - "id":"0x7411" - } - ], - "routing":"routingmanagerd" -} diff --git a/test/client_id_tests/client_id_test_utility_masked_511.json b/test/client_id_tests/client_id_test_utility_masked_511.json deleted file mode 100644 index a57d382..0000000 --- a/test/client_id_tests/client_id_test_utility_masked_511.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "unicast":"127.0.0.1", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "diagnosis":"0x62", - "diagnosis_mask":"0xFE00", - "applications": - [ - { - "name":"client_id_test_utility_service_in", - "id":"0x6211" - }, - { - "name":"client_id_test_utility_service_in_two", - "id":"0x6212" - }, - { - "name":"client_id_test_utility_service_out_low", - "id":"0x5911" - }, - { - "name":"client_id_test_utility_service_out_high", - "id":"0x7411" - } - ], - "routing":"routingmanagerd" -} diff --git a/test/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_master.json.in b/test/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_master.json.in deleted file mode 100644 index a986dd9..0000000 --- a/test/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_master.json.in +++ /dev/null @@ -1,70 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"client_id_test_service_one", - "id":"0x1111" - }, - { - "name":"client_id_test_service_two", - "id":"0x2222" - }, - { - "name":"client_id_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1000", - "instance":"0x0001", - "unreliable":"30001", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2000", - "instance":"0x0001", - "unreliable":"30002", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3000", - "instance":"0x0001", - "unreliable":"30003", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - } - } - ], - "routing":"client_id_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} \ No newline at end of file diff --git a/test/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_slave.json.in b/test/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_slave.json.in deleted file mode 100644 index 596f842..0000000 --- a/test/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_slave.json.in +++ /dev/null @@ -1,70 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"client_id_test_service_four", - "id":"0x4444" - }, - { - "name":"client_id_test_service_five", - "id":"0x5555" - }, - { - "name":"client_id_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4000", - "instance":"0x0001", - "unreliable":"30004", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5000", - "instance":"0x0001", - "unreliable":"30005", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6000", - "instance":"0x0001", - "unreliable":"30006", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - } - } - ], - "routing":"client_id_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} \ No newline at end of file diff --git a/test/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_master.json.in b/test/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_master.json.in deleted file mode 100644 index bb3507b..0000000 --- a/test/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_master.json.in +++ /dev/null @@ -1,70 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"client_id_test_service_one", - "id":"0x1111" - }, - { - "name":"client_id_test_service_two", - "id":"0x2222" - }, - { - "name":"client_id_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1000", - "instance":"0x0001", - "unreliable":"30001", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2000", - "instance":"0x0001", - "unreliable":"30002", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3000", - "instance":"0x0001", - "unreliable":"30003", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - } - ], - "routing":"client_id_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} \ No newline at end of file diff --git a/test/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_slave.json.in b/test/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_slave.json.in deleted file mode 100644 index a7337e9..0000000 --- a/test/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_slave.json.in +++ /dev/null @@ -1,70 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"client_id_test_service_four", - "id":"0x4444" - }, - { - "name":"client_id_test_service_five", - "id":"0x5555" - }, - { - "name":"client_id_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4000", - "instance":"0x0001", - "unreliable":"30004", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5000", - "instance":"0x0001", - "unreliable":"30005", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6000", - "instance":"0x0001", - "unreliable":"30006", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - } - ], - "routing":"client_id_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} \ No newline at end of file diff --git a/test/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_master.json.in b/test/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_master.json.in deleted file mode 100644 index 9f7062f..0000000 --- a/test/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_master.json.in +++ /dev/null @@ -1,70 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"client_id_test_service_one", - "id":"0x1111" - }, - { - "name":"client_id_test_service_two", - "id":"0x2222" - }, - { - "name":"client_id_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1000", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2000", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3000", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - } - ], - "routing":"client_id_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} \ No newline at end of file diff --git a/test/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_slave.json.in b/test/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_slave.json.in deleted file mode 100644 index 1aaf2cb..0000000 --- a/test/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_slave.json.in +++ /dev/null @@ -1,70 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"client_id_test_service_four", - "id":"0x4444" - }, - { - "name":"client_id_test_service_five", - "id":"0x5555" - }, - { - "name":"client_id_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4000", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5000", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6000", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - } - ], - "routing":"client_id_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} \ No newline at end of file diff --git a/test/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_master.json.in b/test/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_master.json.in deleted file mode 100644 index a986dd9..0000000 --- a/test/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_master.json.in +++ /dev/null @@ -1,70 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"client_id_test_service_one", - "id":"0x1111" - }, - { - "name":"client_id_test_service_two", - "id":"0x2222" - }, - { - "name":"client_id_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1000", - "instance":"0x0001", - "unreliable":"30001", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2000", - "instance":"0x0001", - "unreliable":"30002", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3000", - "instance":"0x0001", - "unreliable":"30003", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - } - } - ], - "routing":"client_id_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} \ No newline at end of file diff --git a/test/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_slave.json.in b/test/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_slave.json.in deleted file mode 100644 index 2acb37b..0000000 --- a/test/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_slave.json.in +++ /dev/null @@ -1,70 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"client_id_test_service_four", - "id":"0x1111" - }, - { - "name":"client_id_test_service_five", - "id":"0x2222" - }, - { - "name":"client_id_test_service_six", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x4000", - "instance":"0x0001", - "unreliable":"30004", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5000", - "instance":"0x0001", - "unreliable":"30005", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6000", - "instance":"0x0001", - "unreliable":"30006", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - } - } - ], - "routing":"client_id_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} \ No newline at end of file diff --git a/test/client_id_tests/conf/client_id_test_same_client_ids_same_ports_master.json.in b/test/client_id_tests/conf/client_id_test_same_client_ids_same_ports_master.json.in deleted file mode 100644 index 9f7062f..0000000 --- a/test/client_id_tests/conf/client_id_test_same_client_ids_same_ports_master.json.in +++ /dev/null @@ -1,70 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"client_id_test_service_one", - "id":"0x1111" - }, - { - "name":"client_id_test_service_two", - "id":"0x2222" - }, - { - "name":"client_id_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1000", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2000", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3000", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - } - ], - "routing":"client_id_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} \ No newline at end of file diff --git a/test/client_id_tests/conf/client_id_test_same_client_ids_same_ports_slave.json.in b/test/client_id_tests/conf/client_id_test_same_client_ids_same_ports_slave.json.in deleted file mode 100644 index ae534b1..0000000 --- a/test/client_id_tests/conf/client_id_test_same_client_ids_same_ports_slave.json.in +++ /dev/null @@ -1,70 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"client_id_test_service_four", - "id":"0x1111" - }, - { - "name":"client_id_test_service_five", - "id":"0x2222" - }, - { - "name":"client_id_test_service_six", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x4000", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5000", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6000", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - } - ], - "routing":"client_id_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} \ No newline at end of file diff --git a/test/common/examples_policies/vsomeip/0_0/vsomeip_security.json b/test/common/examples_policies/vsomeip/0_0/vsomeip_security.json new file mode 100644 index 0000000..ab1b06b --- /dev/null +++ b/test/common/examples_policies/vsomeip/0_0/vsomeip_security.json @@ -0,0 +1,255 @@ +{ + "security": { + "policies": [ + { + "credentials": { + "gid": "0", + "uid": "0" + }, + "deny": {} + }, + { + "deny": { + "requests": [ + { + "instance": "any", + "service": "0x40" + } + ] + }, + "credentials": { + "gid": "9999", + "uid": "9999" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "0" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91b" + }, + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4002200", + "uid": "4002200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4003014", + "uid": "4003014" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "4003015" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "5004", + "uid": "4003021" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91f" + }, + { + "instance": "any", + "service": "0xf8c7" + } + ] + }, + "credentials": { + "gid": "4003024", + "uid": "4003024" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4003025", + "uid": "4003025" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4003026", + "uid": "4003026" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91f" + } + ] + }, + "credentials": { + "gid": "4003029", + "uid": "4003029" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf913" + } + ] + }, + "credentials": { + "gid": "4003031", + "uid": "4003031" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xb025" + }, + { + "instance": "any", + "service": "0xb024" + }, + { + "instance": "any", + "service": "0xb021" + } + ] + }, + "credentials": { + "gid": "4004200", + "uid": "4004201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91f" + } + ] + }, + "credentials": { + "gid": "4013201", + "uid": "4013201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91f" + } + ] + }, + "credentials": { + "gid": "4013210", + "uid": "4013210" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91b" + } + ] + }, + "credentials": { + "gid": "4017205", + "uid": "4017205" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "4002200", + "4003014" + ], + "uid": [ + "4002200", + "4003014" + ] + } + ] + } + } + ] + } +} diff --git a/test/common/examples_policies/vsomeip/4002200_4002200/vsomeip_security.json b/test/common/examples_policies/vsomeip/4002200_4002200/vsomeip_security.json new file mode 100644 index 0000000..221d035 --- /dev/null +++ b/test/common/examples_policies/vsomeip/4002200_4002200/vsomeip_security.json @@ -0,0 +1,1556 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8ac" + }, + { + "instance": "any", + "service": "0x102d" + }, + { + "instance": "any", + "service": "0x102e" + }, + { + "instance": "any", + "service": "0xf8a5" + }, + { + "instance": "any", + "service": "0xf8a7" + }, + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0x1023" + }, + { + "instance": "any", + "service": "0xf8aa" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a2" + }, + { + "instance": "any", + "service": "0x1002" + }, + { + "instance": "any", + "service": "0xf8ab" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ], + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xfea8" + }, + { + "instance": "any", + "service": "0xfe8c" + }, + { + "instance": "any", + "service": "0xf91b" + }, + { + "instance": "any", + "service": "0x101c" + }, + { + "instance": "any", + "service": "0xfe9c" + }, + { + "instance": "any", + "service": "0xb51a" + }, + { + "instance": "any", + "service": "0xfeaa" + }, + { + "instance": "any", + "service": "0xb510" + }, + { + "instance": "any", + "service": "0xfa60" + }, + { + "instance": "any", + "service": "0xf917" + }, + { + "instance": "any", + "service": "0xfeac" + }, + { + "instance": "any", + "service": "0xfe87" + }, + { + "instance": "any", + "service": "0xfe8a" + }, + { + "instance": "any", + "service": "0xfe86" + }, + { + "instance": "any", + "service": "0xfe88" + }, + { + "instance": "any", + "service": "0xfeab" + }, + { + "instance": "any", + "service": "0xfe9d" + }, + { + "instance": "any", + "service": "0xfea3" + }, + { + "instance": "any", + "service": "0xfea6" + }, + { + "instance": "any", + "service": "0xfe8e" + }, + { + "instance": "any", + "service": "0xfe9f" + }, + { + "instance": "any", + "service": "0xfe92" + }, + { + "instance": "any", + "service": "0xb519" + }, + { + "instance": "any", + "service": "0xfe8d" + }, + { + "instance": "any", + "service": "0xfe83" + }, + { + "instance": "any", + "service": "0xfeae" + }, + { + "instance": "any", + "service": "0xfe81" + }, + { + "instance": "any", + "service": "0xfe98" + }, + { + "instance": "any", + "service": "0xfe85" + }, + { + "instance": "any", + "service": "0xfea7" + }, + { + "instance": "any", + "service": "0xfea1" + }, + { + "instance": "any", + "service": "0xfead" + }, + { + "instance": "any", + "service": "0xfe93" + }, + { + "instance": "any", + "service": "0xfe8b" + }, + { + "instance": "any", + "service": "0xfea5" + }, + { + "instance": "any", + "service": "0x1534" + }, + { + "instance": "any", + "service": "0xfeaf" + }, + { + "instance": "any", + "service": "0xf912" + }, + { + "instance": "any", + "service": "0x1506" + }, + { + "instance": "any", + "service": "0xfe90" + }, + { + "instance": "any", + "service": "0x101d" + }, + { + "instance": "any", + "service": "0xfea9" + }, + { + "instance": "any", + "service": "0xf911" + }, + { + "instance": "any", + "service": "0x1001" + }, + { + "instance": "any", + "service": "0xfe9a" + }, + { + "instance": "any", + "service": "0xfe97" + }, + { + "instance": "any", + "service": "0x9001" + }, + { + "instance": "any", + "service": "0xf913" + }, + { + "instance": "any", + "service": "0xfe9e" + }, + { + "instance": "any", + "service": "0xb513" + }, + { + "instance": "any", + "service": "0xfeb0" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + }, + { + "instance": "any", + "service": "0xfe89" + }, + { + "instance": "any", + "service": "0xfe82" + }, + { + "instance": "any", + "service": "0x1536" + }, + { + "instance": "any", + "service": "0x1531" + }, + { + "instance": "any", + "service": "0xfea4" + }, + { + "instance": "any", + "service": "0xfe9b" + }, + { + "instance": "any", + "service": "0xfe99" + }, + { + "instance": "any", + "service": "0xfe95" + }, + { + "instance": "any", + "service": "0xfe84" + }, + { + "instance": "any", + "service": "0xfea2" + }, + { + "instance": "any", + "service": "0xfe91" + }, + { + "instance": "any", + "service": "0xfe94" + } + ] + }, + "credentials": { + "gid": "4002200", + "uid": "4002200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "0", + "uid": "0" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "0" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4003011", + "uid": "4003013" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a2" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4003014", + "uid": "4003014" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "4003015" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4003025", + "uid": "4003025" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4003026", + "uid": "4003026" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4003029", + "uid": "4003029" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4003031", + "uid": "4003031" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4003205", + "uid": "4003205" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4004200", + "uid": "4004201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4005300", + "uid": "4005204" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4006200", + "uid": "4006200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4006201", + "uid": "4006201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4006202", + "uid": "4006202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4006220", + "uid": "4006220" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4006221", + "uid": "4006221" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4006241", + "uid": "4006241" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4007200", + "uid": "4007200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4007210", + "uid": "4007210" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4007211", + "uid": "4007211" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4007212", + "uid": "4007212" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4008300", + "uid": "4008200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4008300", + "uid": "4008203" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4008303", + "uid": "4008205" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4008305", + "uid": "4008207" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8aa" + }, + { + "instance": "any", + "service": "0xf8a2" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4010200", + "uid": "4010200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4011201", + "uid": "4011201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8ab" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012230" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012240" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4013201", + "uid": "4013201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013202", + "uid": "4013202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a4" + }, + { + "instance": "any", + "service": "0xf8a4" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "5501", + "uid": "4013203" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "5510", + "uid": "4013206" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013209", + "uid": "4013209" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013213", + "uid": "4013213" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013214", + "uid": "4013214" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013215", + "uid": "4013215" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013217", + "uid": "4013217" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013218", + "uid": "4013218" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013219", + "uid": "4013219" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013223", + "uid": "4013223" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013225", + "uid": "4013225" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + } + ] + }, + "credentials": { + "gid": "4013229", + "uid": "4013229" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "5510", + "uid": "4013232" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4013233", + "uid": "4013233" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "4013234", + "uid": "4013234" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4013242", + "uid": "4013242" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4014201", + "uid": "4014201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a5" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a2" + } + ] + }, + "credentials": { + "gid": "4014300", + "uid": "4014300" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0x102d" + }, + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a2" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4014390", + "uid": "4014390" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4015210", + "uid": "4015210" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a0" + } + ] + }, + "credentials": { + "gid": "5509", + "uid": "4016203" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a3" + }, + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "5509", + "uid": "4016205" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a2" + } + ] + }, + "credentials": { + "gid": "4017201", + "uid": "4017201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4017202", + "uid": "4017202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4017208", + "uid": "4017208" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a2" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4017209", + "uid": "4017209" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4017210", + "uid": "4017210" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8ac" + }, + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4017211", + "uid": "4017211" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4017215", + "uid": "4017215" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4017216", + "uid": "4017216" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a2" + } + ] + }, + "credentials": { + "gid": "4017219", + "uid": "4017219" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + }, + { + "instance": "any", + "service": "0xf8a2" + } + ] + }, + "credentials": { + "gid": "4017220", + "uid": "4017220" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a4" + } + ] + }, + "credentials": { + "gid": "4017221", + "uid": "4017221" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4018204", + "uid": "4018204" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "4012300", + "4013225", + "4003031", + "4013201", + "4017219", + "4013202", + "4003014", + "4017221", + "4017201", + "4017211", + "4006200", + "4013213", + "4003026", + "4011201", + "4006220", + "4013218", + "4013217", + "0", + "4014300", + "4013215", + "4003019", + "4013207", + "4013211", + "4013223", + "4008303", + "4013220", + "4005300", + "4003205", + "4013219", + "4007210", + "4003024", + "4004200", + "4007234", + "4006202", + "5510", + "4013200" + ], + "uid": [ + "4013232", + "4013225", + "4003031", + "4012201", + "4013201", + "4005202", + "4017219", + "4008205", + "4013202", + "4003014", + "4017221", + "4017201", + "4004201", + "4017211", + "4006200", + "4013213", + "4003026", + "4011201", + "4006220", + "4013218", + "4013217", + "4013206", + "0", + "4014300", + "4013215", + "4003019", + "4013207", + "4013211", + "4013223", + "4013220", + "4003205", + "4013219", + "4007210", + "4012240", + "4003024", + "4007234", + "4006202", + "4013200" + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/test/common/examples_policies/vsomeip/4002201_4002201/vsomeip_security.json b/test/common/examples_policies/vsomeip/4002201_4002201/vsomeip_security.json new file mode 100644 index 0000000..e03049d --- /dev/null +++ b/test/common/examples_policies/vsomeip/4002201_4002201/vsomeip_security.json @@ -0,0 +1,122 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0x1501" + }, + { + "instance": "any", + "service": "0xf8a8" + } + ], + "requests": [ + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + }, + { + "instance": "any", + "service": "0x1532" + } + ] + }, + "credentials": { + "gid": "4002201", + "uid": "4002201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a8" + } + ] + }, + "credentials": { + "gid": "4003024", + "uid": "4003024" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a8" + } + ] + }, + "credentials": { + "gid": "4004200", + "uid": "4004201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0x1501" + } + ] + }, + "credentials": { + "gid": "4006202", + "uid": "4006202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a8" + } + ] + }, + "credentials": { + "gid": "4011201", + "uid": "4011201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a8" + } + ] + }, + "credentials": { + "gid": "5509", + "uid": "4016203" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "4003014" + ], + "uid": [ + "4003014" + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/test/common/examples_policies/vsomeip/4002205_4002205/vsomeip_security.json b/test/common/examples_policies/vsomeip/4002205_4002205/vsomeip_security.json new file mode 100644 index 0000000..9512f8d --- /dev/null +++ b/test/common/examples_policies/vsomeip/4002205_4002205/vsomeip_security.json @@ -0,0 +1,54 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0xf8a6" + } + ], + "requests": [ + { + "instance": "any", + "service": "0xf8c1" + } + ] + }, + "credentials": { + "gid": "4002205", + "uid": "4002205" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8a6" + } + ] + }, + "credentials": { + "gid": "4014300", + "uid": "4014300" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "4003024" + ], + "uid": [ + "4003024" + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/test/common/examples_policies/vsomeip/4003013_4003011/vsomeip_security.json b/test/common/examples_policies/vsomeip/4003013_4003011/vsomeip_security.json new file mode 100644 index 0000000..da35eb4 --- /dev/null +++ b/test/common/examples_policies/vsomeip/4003013_4003011/vsomeip_security.json @@ -0,0 +1,64 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0xf8d0" + } + ], + "requests": [ + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf8a4" + }, + { + "instance": "any", + "service": "0xf8a1" + } + ] + }, + "credentials": { + "gid": "4003011", + "uid": "4003013" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8d0" + } + ] + }, + "credentials": { + "gid": "4003025", + "uid": "4003025" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "4002200", + "4003014" + ], + "uid": [ + "4002200", + "4003014" + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/test/common/examples_policies/vsomeip/4003014_4003014/vsomeip_security.json b/test/common/examples_policies/vsomeip/4003014_4003014/vsomeip_security.json new file mode 100644 index 0000000..0de3d03 --- /dev/null +++ b/test/common/examples_policies/vsomeip/4003014_4003014/vsomeip_security.json @@ -0,0 +1,1306 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xb067" + }, + { + "instance": "any", + "service": "0xf8c4" + }, + { + "instance": "any", + "service": "0xfe85" + }, + { + "instance": "any", + "service": "0xb0a7" + }, + { + "instance": "any", + "service": "0xb0a8" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ], + "requests": [ + { + "instance": "any", + "service": "0x1531" + }, + { + "instance": "any", + "service": "0xb519" + }, + { + "instance": "any", + "service": "0xf8c2" + }, + { + "instance": "any", + "service": "0x1024" + }, + { + "instance": "any", + "service": "0x1397" + }, + { + "instance": "any", + "service": "0xb504" + }, + { + "instance": "any", + "service": "0xf8a0" + }, + { + "instance": "any", + "service": "0xf913" + }, + { + "instance": "any", + "service": "0xb020" + }, + { + "instance": "any", + "service": "0xb0a7" + }, + { + "instance": "any", + "service": "0xf8a2" + }, + { + "instance": "any", + "service": "0xb0a8" + }, + { + "instance": "any", + "service": "0xf918" + }, + { + "instance": "any", + "service": "0x1032" + }, + { + "instance": "any", + "service": "0xf8a4" + }, + { + "instance": "any", + "service": "0x1533" + } + ] + }, + "credentials": { + "gid": "4003014", + "uid": "4003014" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "0", + "uid": "0" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8c4" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "0" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4004200", + "uid": "1041" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xfe85" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4002200", + "uid": "4002200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4002201", + "uid": "4002201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003011", + "uid": "4003013" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8c4" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "4003015" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003019", + "uid": "4003019" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003022", + "uid": "4003022" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003024", + "uid": "4003024" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8c4" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4003025", + "uid": "4003025" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003026", + "uid": "4003026" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003027", + "uid": "4003027" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003028", + "uid": "4003028" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4003031", + "uid": "4003031" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003036", + "uid": "4003036" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003203", + "uid": "4003203" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003205", + "uid": "4003205" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4003207", + "uid": "4003207" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4004200", + "uid": "4004201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4006200", + "uid": "4006200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + } + ] + }, + "credentials": { + "gid": "4006202", + "uid": "4006202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4006220", + "uid": "4006220" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4006221", + "uid": "4006221" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4006222", + "uid": "4006222" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + } + ] + }, + "credentials": { + "gid": "4006241", + "uid": "4006241" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4007200", + "uid": "4007200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xb0a7" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4007210", + "uid": "4007210" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xb0a7" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4007211", + "uid": "4007211" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4007234", + "uid": "4007234" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4008300", + "uid": "4008202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4008300", + "uid": "4008204" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xb067" + }, + { + "instance": "any", + "service": "0xb0a7" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4010200", + "uid": "4010200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4011201", + "uid": "4011201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012202" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012203" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012220" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012230" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012232" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4012300", + "uid": "4012240" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4013200", + "uid": "4013200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4013201", + "uid": "4013201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "5510", + "uid": "4013206" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4013211", + "uid": "4013211" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4013212", + "uid": "4013212" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4013213", + "uid": "4013213" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4013214", + "uid": "4013214" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4013218", + "uid": "4013218" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4013219", + "uid": "4013219" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xb067" + } + ] + }, + "credentials": { + "gid": "4013220", + "uid": "4013220" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "5510", + "uid": "4013232" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4014201", + "uid": "4014201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf902" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4014300", + "uid": "4014300" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4014390", + "uid": "4014390" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4015200", + "uid": "4015200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4015201", + "uid": "4015201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "5509", + "uid": "4016203" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "5509", + "uid": "4016204" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "5509", + "uid": "4016205" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017200", + "uid": "4017200" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017201", + "uid": "4017201" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017208", + "uid": "4017208" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017209", + "uid": "4017209" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017210", + "uid": "4017210" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017211", + "uid": "4017211" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017215", + "uid": "4017215" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017216", + "uid": "4017216" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf91c" + }, + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017218", + "uid": "4017218" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017219", + "uid": "4017219" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017220", + "uid": "4017220" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf901" + } + ] + }, + "credentials": { + "gid": "4017221", + "uid": "4017221" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "0", + "4003016", + "4004200", + "4013207", + "4003015", + "4002200", + "4013200" + ], + "uid": [ + "0", + "4003016", + "4004201", + "4013207", + "4003015", + "4002200", + "4013200" + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/test/common/examples_policies/vsomeip/4003015_4003015/vsomeip_security.json b/test/common/examples_policies/vsomeip/4003015_4003015/vsomeip_security.json new file mode 100644 index 0000000..20f0b47 --- /dev/null +++ b/test/common/examples_policies/vsomeip/4003015_4003015/vsomeip_security.json @@ -0,0 +1,82 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0xf918" + } + ], + "requests": [ + { + "instance": "any", + "service": "0xf8c4" + }, + { + "instance": "any", + "service": "0xf90c" + }, + { + "instance": "any", + "service": "0xf913" + }, + { + "instance": "any", + "service": "0xf901" + }, + { + "instance": "any", + "service": "0xf8a4" + }, + { + "instance": "any", + "service": "0xf902" + } + ] + }, + "credentials": { + "gid": "4003015", + "uid": "4003015" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf918" + } + ] + }, + "credentials": { + "gid": "4003014", + "uid": "4003014" + } + }, + { + "credentials": { + "allow": [ + { + "gid": [ + "4003014", + "0", + "4013207", + "4003203", + "4002200" + ], + "uid": [ + "4003014", + "0", + "4013207", + "4003203", + "4002200" + ] + } + ] + } + } + ] + } +} \ No newline at end of file diff --git a/test/common/examples_policies/vsomeip/4003016_4003016/vsomeip_security.json b/test/common/examples_policies/vsomeip/4003016_4003016/vsomeip_security.json new file mode 100644 index 0000000..eedb124 --- /dev/null +++ b/test/common/examples_policies/vsomeip/4003016_4003016/vsomeip_security.json @@ -0,0 +1,63 @@ +{ + "security": { + "policies": [ + { + "allow": { + "offers": [ + { + "instance": "any", + "service": "0xf8c2" + } + ], + "requests": [] + }, + "credentials": { + "gid": "4003016", + "uid": "4003016" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8c2" + } + ] + }, + "credentials": { + "gid": "4003014", + "uid": "4003014" + } + }, + { + "allow": { + "requests": [ + { + "instance": "any", + "service": "0xf8c2" + } + ] + }, + "credentials": { + "gid": "4013202", + "uid": "4013202" + } + }, + { + "deny": { + "offers": [ + { + "instance": "any", + "service": "0x40" + } + ] + }, + "credentials": { + "gid": "9000", + "uid": "9000" + } + } + ] + } +} diff --git a/test/common/examples_policies/vsomeip/vsomeip_policy_extensions.json b/test/common/examples_policies/vsomeip/vsomeip_policy_extensions.json new file mode 100644 index 0000000..5199326 --- /dev/null +++ b/test/common/examples_policies/vsomeip/vsomeip_policy_extensions.json @@ -0,0 +1 @@ +{"container_policy_extensions": [{"container": "android-rse", "path": "../vsomeip_ext/android"}, {"container": "android-idc", "path": "../vsomeip_ext/android"}, {"container": "android-idc-base", "path": "../vsomeip_ext/android"}]} diff --git a/test/common/examples_policies/vsomeip/vsomeip_security.json b/test/common/examples_policies/vsomeip/vsomeip_security.json new file mode 100644 index 0000000..d278ea8 --- /dev/null +++ b/test/common/examples_policies/vsomeip/vsomeip_security.json @@ -0,0 +1,25 @@ +{ + "routing-credentials": { + "gid": "5002", + "uid": "4003017" + }, + "security": { + "check_credentials": "true", + "policies": [ + { + "allow": {}, + "credentials": { + "gid": "5002", + "uid": "4003017" + } + }, + { + "credentials": { + "gid": "0", + "uid": "0" + }, + "deny": {} + } + ] + } +} diff --git a/test/common/utility.cpp b/test/common/utility.cpp new file mode 100644 index 0000000..478deeb --- /dev/null +++ b/test/common/utility.cpp @@ -0,0 +1,235 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "utility.hpp" + +void +utility::load_policy_data(std::string _input, + std::vector &_elements, + std::set &_failed) { + + boost::property_tree::ptree its_tree; + try { + boost::property_tree::json_parser::read_json(_input, its_tree); + _elements.push_back({ _input, its_tree }); + } + catch (boost::property_tree::json_parser_error &e) { + _failed.insert(_input); + } +} + +void +utility::read_data(const std::set &_input, + std::vector &_elements, + std::set &_failed) { + + for (auto i : _input) { + if (vsomeip_v3::utility::is_file(i)) { + load_policy_data(i, _elements, _failed); + } else if (vsomeip_v3::utility::is_folder(i)) { + std::map its_names; + boost::filesystem::path its_path(i); + for (auto j = boost::filesystem::directory_iterator(its_path); + j != boost::filesystem::directory_iterator(); + j++) { + std::string name = j->path().string() + "/vsomeip_security.json"; + if (vsomeip_v3::utility::is_file(name)) + its_names[name] = true; + } + + for (const auto& n : its_names) + load_policy_data(n.first, _elements, _failed); + } + } +} + +std::set +utility::get_all_files_in_dir(const std::string &_dir_path, + const std::vector &_dir_skip_list) { + + // Create a vector of string + std::set list_of_files; + try { + // Check if given path exists and points to a directory + if (boost::filesystem::exists(_dir_path) + && boost::filesystem::is_directory(_dir_path)) { + // Create a Recursive Directory Iterator object and points to the + // starting of directory + boost::filesystem::recursive_directory_iterator iter(_dir_path); + // Create a Recursive Directory Iterator object pointing to end. + boost::filesystem::recursive_directory_iterator end; + // Iterate till end + while (iter != end) { + // Check if current entry is a directory and if exists in + // skip list + if (boost::filesystem::is_directory(iter->path()) + && (std::find(_dir_skip_list.begin(), + _dir_skip_list.end(), iter->path().filename()) + != _dir_skip_list.end())) { + // Boost Filesystem API to skip current directory iteration +#if VSOMEIP_BOOST_VERSION < 108100 + iter.no_push(); +#else + iter.disable_recursion_pending(); +#endif + } else { + // Add the name in vector + list_of_files.insert(iter->path().string()); + } + boost::system::error_code ec; + // Increment the iterator to point to next entry in recursive iteration + iter.increment(ec); + if (ec) { + std::cerr << "Error While Accessing : " << iter->path().string() << " :: " << ec.message() << '\n'; + } + } + } + } + catch (std::system_error & e) { + std::cerr << "Exception :: " << e.what(); + } + return list_of_files; +} + +std::string +utility::get_policies_path() { + + return boost::filesystem::canonical( + boost::filesystem::current_path()).string() + + "/../test/common/examples_policies"; +} + +vsomeip_sec_client_t +utility::create_uds_client(uid_t user, gid_t group) { + vsomeip_sec_client_t result; + result.client_type = VSOMEIP_CLIENT_UDS; + result.client.uds_client = { user, group }; + return result; +} + +void +utility::force_check_credentials( + std::vector &_policy_elements, + std::string _value) { + + for(auto &i : _policy_elements) { + try { + boost::property_tree::ptree &security + = i.tree_.get_child("security"); + boost::property_tree::ptree &credentials + = security.get_child("check_credentials"); + if (credentials.get_value().compare(_value)) { + security.erase("check_credentials"); + credentials.put("check_credentials", _value); + } + } + catch(...) {} + } + } + +void utility::get_policy_uids(vsomeip_v3::configuration_element &_policy_element, + std::vector &_out_uids) +{ + try { + std::vector user_ids; + auto policy_tree = _policy_element.tree_.get_child("security.policies"); + for (auto policy_node : policy_tree) { + auto optional_credential_node = + policy_node.second.get_child_optional("credentials.uid"); + if (optional_credential_node) { + auto optional_user_id = + optional_credential_node.get().get_value_optional(); + if (optional_user_id) { + user_ids.push_back(optional_user_id.get()); + } + } + } + for (const std::string &uid_string : user_ids) { + _out_uids.push_back((vsomeip_v3::uid_t)std::strtoul(uid_string.c_str(), NULL, 0)); + } + } catch (...) { + std::cerr << "Caught exception while reading user ids in policy element \"" + << _policy_element.name_ << "\"!" << std::endl; + } +} + +void utility::get_policy_services(vsomeip_v3::configuration_element &_policy_element, + std::vector &_out_services) +{ + try { + std::vector services; + auto policy_tree = _policy_element.tree_.get_child("security.policies"); + for (auto policy_node : policy_tree) { + // Get allowed request services. + auto allow_requests = policy_node.second.get_child_optional("allow.requests"); + if (allow_requests) { + for (auto &request_node : allow_requests.get()) { + auto optional_service = request_node.second.get_child("service") + .get_value_optional(); + if (optional_service) { + services.push_back(optional_service.get()); + } + } + } + // Get denied request services. + auto deny_requests = policy_node.second.get_child_optional("deny.requests"); + if (deny_requests) { + for (auto &request_node : deny_requests.get()) { + auto optional_service = request_node.second.get_child("service") + .get_value_optional(); + if (optional_service) { + services.push_back(optional_service.get()); + } + } + } + } + for (const std::string &service_str : services) { + _out_services.push_back( + (vsomeip_v3::service_t)std::strtoul(service_str.c_str(), NULL, 0)); + } + } catch (...) { + std::cerr << "Caught exception while reading services in policy element \"" + << _policy_element.name_ << "\"!" << std::endl; + } +} + +void utility::add_security_whitelist(vsomeip_v3::configuration_element &_policy_element, + const bool _check_whitelist) +{ + std::vector user_ids; + get_policy_uids(_policy_element, user_ids); + + std::vector services; + get_policy_services(_policy_element, services); + + add_security_whitelist(_policy_element, user_ids, services, _check_whitelist); +} + +void utility::add_security_whitelist(vsomeip_v3::configuration_element &_policy_element, + const std::vector &_user_ids, + const std::vector &_services, + const bool _check_whitelist) +{ + // Add the user ids to the whitelist. + boost::property_tree::ptree id_array_node; + for (auto user_id : _user_ids) { + boost::property_tree::ptree id_node; + id_node.put("", user_id); + id_array_node.push_back(std::make_pair("", id_node)); + } + _policy_element.tree_.add_child("security-update-whitelist.uids", id_array_node); + + // Add the services to the whitelist. + boost::property_tree::ptree service_array_node; + for (auto service : _services) { + boost::property_tree::ptree service_node; + service_node.put("", service); + service_array_node.push_back(std::make_pair("", service_node)); + } + _policy_element.tree_.add_child("security-update-whitelist.services", service_array_node); + + // Update the 'check_whitelist' flag. + _policy_element.tree_.add("security-update-whitelist.check-whitelist", _check_whitelist); +} diff --git a/test/common/utility.hpp b/test/common/utility.hpp new file mode 100644 index 0000000..b4f1100 --- /dev/null +++ b/test/common/utility.hpp @@ -0,0 +1,77 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include "../../implementation/security/include/policy_manager_impl.hpp" +#include "../../implementation/configuration/include/configuration_impl.hpp" +#include "../../implementation/utility/include/utility.hpp" + +// This is needed to silence internal warnings in boost, when e.g. including +#define BOOST_BIND_GLOBAL_PLACEHOLDERS + +#include +#include +#include + +#include + +class utility { +public: + static void load_policy_data(std::string _input, + std::vector &_elements, + std::set &_failed); + + static void read_data(const std::set &_input, + std::vector &_elements, std::set &_failed); + + static std::set get_all_files_in_dir(const std::string &_dir_path, + const std::vector &_dir_skip_list); + + static std::string get_policies_path(); + + static vsomeip_sec_client_t create_uds_client(uid_t user, gid_t group); + + static void force_check_credentials(std::vector &_policy_elements, std::string _value); + /** + * @brief Get all of the user ids in the given policy element. + * + * @param _policy_element + * @param _out_uids + */ + static void get_policy_uids(vsomeip_v3::configuration_element &_policy_element, + std::vector &_out_uids); + + /** + * @brief Get all of the services in the given policy element. + * + * @param _policy_element + * @param _out_services + */ + static void get_policy_services(vsomeip_v3::configuration_element &_policy_element, + std::vector &_out_services); + + /** + * @brief Add a security whitelist to the given policy element. Uses all user ids and + * services mentioned in the policy. + * + * @param _policy_element + * @param _check_whitelist + */ + static void add_security_whitelist(vsomeip_v3::configuration_element &_policy_element, + const bool _check_whitelist); + + /** + * @brief Add a security whitelist with the given ids and services to the policy element. + * + * @param _policy_element + * @param _user_ids + * @param _services + * @param _check_whitelist + */ + static void add_security_whitelist(vsomeip_v3::configuration_element &_policy_element, + const std::vector &_user_ids, + const std::vector &_services, + const bool _check_whitelist); +}; diff --git a/test/configuration_tests/configuration-test-deprecated.json b/test/configuration_tests/configuration-test-deprecated.json deleted file mode 100644 index 5a8b0ee..0000000 --- a/test/configuration_tests/configuration-test-deprecated.json +++ /dev/null @@ -1,496 +0,0 @@ -{ - "unicast" : "10.0.2.15", - "diagnosis" : "85", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : { "enable" : "true", "path" : "/home/someip/another-file.log" }, - "dlt" : "false", - "version" : { - "enable" : "false", - "interval" : "15" - } - }, - "watchdog" : - { - "enable" : "true", - "timeout" : "1234", - "allowed_missing_pongs" : "7" - }, - "file-permissions" : - { - "permissions-shm" : "444", - "permissions-uds" : "222" - }, - "supports_selective_broadcasts" : - { - "address" : "160.160.160.160" - }, - "tracing" : - { - "enable" : "true", - "sd_enable" : "true", - "channels" : - [ - { - "name" : "testname", - "id" : "testid" - }, - { - "name" : "testname2", - "id" : "testid2" - }, - { - "name" : "testname3", - "id" : "testid3" - }, - { - "name" : "testname4", - "id" : "testid4" - } - ], - "filters" : - [ - { - "channel" : "testname", - "services" : ["0x1111",2222], - "type" : "positive" - }, - { - "channel" : "testname2", - "services" : ["0x3333",4444], - "type" : "negative" - } - ] - }, - "applications" : - [ - { - "name" : "my_application", - "id" : "0x7788", - "max_dispatchers" : "25", - "max_dispatch_time" : "1234", - "threads" : "12", - "request_debounce_time" : "5000", - "plugins" : - [ - { - "application_plugin" : "testlibraryname" - }, - { - "intentionally_wrong_plugin" : "wrong" - } - ] - }, - { - "name" : "other_application", - "id" : "0x9933", - "threads" : "0", - "threads" : "256", - "request_debounce_time" : "10001" - } - ], - "servicegroups" : - [ - { - "name" : "default", - "unicast" : "local", - "delays" : - { - "initial" : { "minimum" : "10", "maximum" : "100" }, - "repetition-base" : "200", - "repetition-max" : "7", - "cyclic-offer" : "2132", - "cyclic-request" : "2001", - "ttl" : "5" - }, - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x0022", - "reliable" : { "port" : "30506", "enable-magic-cookies" : "true" }, - "unreliable" : "31000", - "events" : - [ - { - "event" : "0x0778", - "is_field" : "false" - }, - { - "event" : "0x779", - "is_field" : "true" - }, - { - "event" : "0x77A", - "is_field" : "false" - } - ], - "eventgroups" : - [ - { - "eventgroup" : "0x4567", - "multicast" : "225.226.227.228", - "events" : [ "0x778", "0x779" ] - }, - { - "eventgroup" : "0x4569", - "multicast" : "225.227.227.228", - "events" : [ "0x779", "0x77A" ] - }, - { - "eventgroup" : "0x4569", - "multicast" : "225.222.227.228", - "events" : [ "0x778", "0x77A" ] - } - ] - }, - { - "service" : "0x1234", - "instance" : "0x0023", - "reliable" : "30503" - }, - { - "service" : "0x7809", - "instance" : "0x1", - "multicast" : - { - "address" : "224.212.244.225", - "port" : "1234" - }, - "eventgroups" : - [ - { - "eventgroup" : "0x1111", - "threshold" : "8", - "is_multicast" : "true", - "events" : [ "0x778", "0x77A" ] - } - ] - } - ] - }, - { - "name" : "extra", - "unicast" : "local", - "delays" : - { - "initial" : { "minimum" : "10", "maximum" : "100" }, - "repetition-base" : "200", - "repetition-max" : "7", - "cyclic-offer" : "2132", - "cyclic-request" : "2001", - "ttl" : "5" - }, - "services" : - [ - { - "service" : "0x2277", - "instance" : "0x0022", - "reliable" : { "port" : "30505" }, - "unreliable" : "31001" - }, - { - "service" : "0x2266", - "instance" : "0x0022", - "reliable" : "30505", - "unreliable" : "30507" - }, - { - "service" : "0x3333", - "instance" : "0x1" - }, - { - "service" : "0x3555", - "instance" : "0x1", - "protocol" : "other" - } - ] - }, - { - "name" : "remote", - "unicast" : "10.0.2.23", - "services" : - [ - { - "service" : "0x4466", - "instance" : "0x0321", - "reliable" : "30506", - "unreliable" : "30444" - } - ] - } - ], - "internal_services" : - [ - { - "first" : "0xF100", - "last" : "0xF109" - }, - { - "first" : { - "service" : "0xF300", - "instance" : "0x1" - }, - "last" : { - "service" : "0xF300", - "instance" : "0x10" - } - } - ], - "clients" : - [ - { - "reliable_remote_ports" : { "first" : "30500", "last" : "30599" }, - "unreliable_remote_ports" : { "first" : "30500", "last" : "30599" }, - "reliable_client_ports" : { "first" : "30491", "last" : "30499" }, - "unreliable_client_ports" : { "first" : "30491", "last" : "30499" } - }, - { - "reliable_remote_ports" : { "first" : "31500", "last" : "31599" }, - "unreliable_remote_ports" : { "first" : "31500", "last" : "31599" }, - "reliable_client_ports" : { "first" : "31491", "last" : "31499" }, - "unreliable_client_ports" : { "first" : "31491", "last" : "31499" } - }, - { - "reliable_remote_ports" : { "first" : "32500", "last" : "32599" }, - "unreliable_remote_ports" : { "first" : "32500", "last" : "32599" }, - "reliable_client_ports" : { "first" : "32491", "last" : "32499" }, - "unreliable_client_ports" : { "first" : "32491", "last" : "32499" } - }, - { - "service" : "0x8888", - "instance" : "0x1", - "unreliable" : [ "0x11", "0x10" ], - "reliable" : [ "0x11", "0x10" ] - }, - { - "service" : "8888", - "instance" : "1", - "unreliable" : [ 40000, 40001 ], - "reliable" : [ 40000, 40001 ] - } - ], - "tcp-restart-aborts-max" : "15", - "tcp-connect-time-max" : "10000", - "max-payload-size-local" : "15000", - "max-payload-size-reliable" : "17000", - "buffer-shrink-threshold" : "11", - "payload-sizes": - [ - { - "unicast":"10.10.10.10", - "ports": - [ - { - "port":"7777", - "max-payload-size":"14999" - } - ] - }, - { - "unicast":"10.10.10.11", - "ports": - [ - { - "port":"7778", - "max-payload-size":"15001" - } - ] - } - ], - "security" : - { - "check_credentials" : "true", - "policies" : - [ - { - "credentials" : { "uid" : "1000", "gid" : "1000" }, - "allow" : - { - "offers": - [ - { - "service" : "0x1234", - "instance" : "0x5678" - }, - { - "service" : "0x1235", - "instance" : "0x5678" - }, - { - "service" : "0x1236", - "instances" : [{ "first" : "0x5675", "last" : "0x5677"}, "0x5678"] - } - ] - } - }, - { - "credentials" : { "uid" : "2000", "gid" : "2000" }, - "allow" : - { - "requests": - [ - { - "service" : "0x1234", - "instances" : [ - { - "ids" : ["0x5678", { "first" : "0x5679", "last" : "0x5699"}], - "methods" : [ "0x0001", { "first" : "0x8001", "last" : "0x8006" }] - } - ] - }, - { - "service" : "0x1237", - "instances" : [ - { - "ids" : ["0x5678"], - "methods" : "any" - } - ] - }, - { - "service" : "0x1238", - "instances" : [ - { - "ids" : "any", - "methods" : ["0x0001"] - } - ] - } - ] - } - }, - { - "credentials" : { "uid" : "4000", "gid" : "4000" }, - "deny" : - { - "requests": - [ - { - "service" : "0x1234", - "instances" : [ - { - "ids" : ["0x5678", { "first" : "0x5679", "last" : "0x5699"}], - "methods" : [ "0x0002", { "first" : "0x9001", "last" : "0x9006" }] - } - ] - } - ], - "offers": - [ - { - "service" : "0x1234", - "instance" : "0x5678" - }, - { - "service" : "0x1235", - "instance" : "0x5678" - }, - { - "service" : "0x1236", - "instances" : [{ "first" : "0x5675", "last" : "0x5677"}, "0x5678"] - } - ] - } - }, - { - "credentials" : { "uid" : "5000", "gid" : "5000" }, - "deny" : - { - } - }, - { - "credentials" : { "uid" : "6000", "gid" : "6000" }, - "allow" : - { - } - }, - { - "credentials" : { "uid" : "7000", "gid" : "7000" }, - "deny" : - { - "requests": - [ - { - "service" : "0x1234", - "instances" : [ - { - "ids" : ["0x5678"], - "methods" : "any" - } - ] - } - ] - } - }, - { - "credentials" : { "uid" : "8000", "gid" : "8000" }, - "allow" : - { - "requests": - [ - { - "service" : "0x1234", - "instances" : [ - { - "ids" : ["0x5678"], - "methods" : "any" - } - ] - } - ] - } - }, - { - "credentials" : { - "allow": [ - { - "uid": [ - "9000" - ], - "gid": [ - "9000" - ] - } - ] - }, - "deny" : - { - } - } - ] - }, - "security-update-whitelist" : - { - "uids" : - [ - {"first" : "1000", "last" : "1008"}, - {"first" : "1100", "last" : "1200"}, - "2000", - "3000" - ], - "services" : - [ - {"first" : "0x1234", "last" : "0x1238"}, - {"first" : "0x2000", "last" : "0x2500"}, - "0x7800" - ], - "check-whitelist" : "true" - }, - "routing" : "my_application", - "routing-credentials" : - { - "uid" : "0x123", - "gid" : "0x456" - }, - "service-discovery" : - { - "enable" : "true", - "protocol" : "udp", - "multicast" : "224.212.244.223", - "port" : "30666", - "offer_debounce_time" : "1000" - } -} diff --git a/test/configuration_tests/configuration-test.cpp b/test/configuration_tests/configuration-test.cpp deleted file mode 100644 index ad4faa7..0000000 --- a/test/configuration_tests/configuration-test.cpp +++ /dev/null @@ -1,811 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include - -#include - -#include -#include -#include -#include "../implementation/configuration/include/configuration.hpp" - -#include "../../implementation/plugin/include/plugin_manager_impl.hpp" -#include "../../implementation/configuration/include/configuration_impl.hpp" -#include "../../implementation/configuration/include/configuration_plugin.hpp" -#include "../../implementation/security/include/security_impl.hpp" - -namespace vsomeip = vsomeip_v3; - -#define CONFIGURATION_FILE "configuration-test.json" -#define DEPRECATED_CONFIGURATION_FILE "configuration-test-deprecated.json" - -#define EXPECTED_UNICAST_ADDRESS "10.0.2.15" - -#define EXPECTED_HAS_CONSOLE true -#define EXPECTED_HAS_FILE true -#define EXPECTED_HAS_DLT false -#define EXPECTED_LOGLEVEL "debug" -#define EXPECTED_LOGFILE "/home/someip/another-file.log" - -#define EXPECTED_ROUTING_MANAGER_HOST "my_application" - -// Logging -#define EXPECTED_VERSION_LOGGING_ENABLED false -#define EXPECTED_VERSION_LOGGING_INTERVAL 15 - -// Application -#define EXPECTED_APPLICATION_MAX_DISPATCHERS 25 -#define EXPECTED_APPLICATION_MAX_DISPATCH_TIME 1234 -#define EXPECTED_APPLICATION_THREADS 12 -#define EXPECTED_APPLICATION_REQUEST_DEBOUNCE_TIME 5000 - -// Services -#define EXPECTED_UNICAST_ADDRESS_1234_0022 EXPECTED_UNICAST_ADDRESS -#define EXPECTED_RELIABLE_PORT_1234_0022 30506 -#define EXPECTED_UNRELIABLE_PORT_1234_0022 31000 - -#define EXPECTED_UNICAST_ADDRESS_1234_0023 EXPECTED_UNICAST_ADDRESS -#define EXPECTED_RELIABLE_PORT_1234_0023 30503 -#define EXPECTED_UNRELIABLE_PORT_1234_0023 vsomeip::ILLEGAL_PORT - -#define EXPECTED_UNICAST_ADDRESS_2277_0022 EXPECTED_UNICAST_ADDRESS -#define EXPECTED_RELIABLE_PORT_2277_0022 30505 -#define EXPECTED_UNRELIABLE_PORT_2277_0022 31001 - -#define EXPECTED_UNICAST_ADDRESS_2266_0022 EXPECTED_UNICAST_ADDRESS -#define EXPECTED_RELIABLE_PORT_2266_0022 30505 -#define EXPECTED_UNRELIABLE_PORT_2266_0022 30507 - -#define EXPECTED_UNICAST_ADDRESS_4466_0321 "10.0.2.23" -#define EXPECTED_RELIABLE_PORT_4466_0321 30506 -#define EXPECTED_UNRELIABLE_PORT_4466_0321 30444 - -// Service Discovery -#define EXPECTED_SD_ENABLED true -#define EXPECTED_SD_PROTOCOL "udp" -#define EXPECTED_SD_MULTICAST "224.212.244.223" -#define EXPECTED_SD_PORT 30666 - -#define EXPECTED_INITIAL_DELAY_MIN 1234 -#define EXPECTED_INITIAL_DELAY_MAX 2345 -#define EXPECTED_REPETITIONS_BASE_DELAY 4242 -#define EXPECTED_REPETITIONS_MAX 4 -#define EXPECTED_TTL 13 -#define EXPECTED_CYCLIC_OFFER_DELAY 2132 -#define EXPECTED_REQUEST_RESPONSE_DELAY 1111 - -#define EXPECTED_DEPRECATED_INITIAL_DELAY_MIN 10 -#define EXPECTED_DEPRECATED_INITIAL_DELAY_MAX 100 -#define EXPECTED_DEPRECATED_REPETITIONS_BASE_DELAY 200 -#define EXPECTED_DEPRECATED_REPETITIONS_MAX 7 -#define EXPECTED_DEPRECATED_TTL 5 -#define EXPECTED_DEPRECATED_REQUEST_RESPONSE_DELAY 2001 - -template -::testing::AssertionResult check(const T &_is, const T &_expected, const std::string &_test) { - if (_is == _expected) { - return ::testing::AssertionSuccess() << "Test \"" << _test << "\" succeeded."; - } else { - return ::testing::AssertionFailure() << "Test \"" << _test << "\" failed! (" - << _is << " != " << _expected << ")"; - } -} - -std::string loglevel_to_string(vsomeip::logger::level_e &_level) { - switch (_level) { - case vsomeip::logger::level_e::LL_FATAL: - return "fatal"; - case vsomeip::logger::level_e::LL_ERROR: - return "error"; - case vsomeip::logger::level_e::LL_WARNING: - return "warning"; - case vsomeip::logger::level_e::LL_INFO: - return "info"; - case vsomeip::logger::level_e::LL_DEBUG: - return "debug"; - case vsomeip::logger::level_e::LL_VERBOSE: - return "verbose"; - default: - return "unknown"; - } -} - -void check_file(const std::string &_config_file, - const std::string &_expected_unicast_address, - bool _expected_has_console, - bool _expected_has_file, - bool _expected_has_dlt, - bool _expected_version_logging_enabled, - uint32_t _expected_version_logging_interval, - uint32_t _expected_application_max_dispatcher, - uint32_t _expected_application_max_dispatch_time, - uint32_t _expected_application_threads, - uint32_t _expected_application_request_debounce_time, - const std::string &_expected_logfile, - const std::string &_expected_loglevel, - const std::string &_expected_unicast_address_1234_0022, - uint16_t _expected_reliable_port_1234_0022, - uint16_t _expected_unreliable_port_1234_0022, - const std::string &_expected_unicast_address_1234_0023, - uint16_t _expected_reliable_port_1234_0023, - uint16_t _expected_unreliable_port_1234_0023, - const std::string &_expected_unicast_address_2277_0022, - uint16_t _expected_reliable_port_2277_0022, - uint16_t _expected_unreliable_port_2277_0022, - const std::string &_expected_unicast_address_2266_0022, - uint16_t _expected_reliable_port_2266_0022, - uint16_t _expected_unreliable_port_2266_0022, - const std::string &_expected_unicast_address_4466_0321, - uint16_t _expected_reliable_port_4466_0321, - uint16_t _expected_unreliable_port_4466_0321, - bool _expected_enabled, - const std::string &_expected_protocol, - const std::string &_expected_multicast, - uint16_t _expected_port, - uint32_t _expected_initial_delay_min, - uint32_t _expected_initial_delay_max, - int32_t _expected_repetitions_base_delay, - uint8_t _expected_repetitions_max, - vsomeip::ttl_t _expected_ttl, - vsomeip::ttl_t _expected_cyclic_offer_delay, - vsomeip::ttl_t _expected_request_response_delay) { - - - // 0. Set environment variable to config file and load it -#ifndef _WIN32 - setenv("VSOMEIP_CONFIGURATION", _config_file.c_str(), 1); -#else - _putenv_s("VSOMEIP_CONFIGURATION", _config_file.c_str() -#endif - - // 1. Create configuration object - std::shared_ptr its_configuration; - auto its_plugin = vsomeip::plugin_manager_impl::get()->get_plugin( - vsomeip::plugin_type_e::CONFIGURATION_PLUGIN, VSOMEIP_CFG_LIBRARY); - if (its_plugin) { - auto its_configuration_plugin - = std::dynamic_pointer_cast(its_plugin); - if (its_configuration_plugin) - its_configuration = its_configuration_plugin->get_configuration(EXPECTED_ROUTING_MANAGER_HOST); - } - - // 2. Did we get a configuration object? - if (0 == its_configuration) { - ADD_FAILURE() << "No configuration object. " - "Either memory overflow or loading error detected!"; - return; - } - - vsomeip::cfg::configuration_impl its_copied_config( - static_cast(*its_configuration)); - vsomeip::cfg::configuration_impl* its_new_config = - new vsomeip::cfg::configuration_impl(its_copied_config); - delete its_new_config; - - its_configuration->set_configuration_path("/my/test/path"); - - // 3. Check host address - boost::asio::ip::address its_host_unicast_address - = its_configuration->get_unicast_address(); - EXPECT_TRUE(check(its_host_unicast_address.to_string(), - _expected_unicast_address, "UNICAST ADDRESS")); - EXPECT_TRUE(its_configuration->is_v4()); - EXPECT_FALSE(its_configuration->is_v6()); - - // check diagnosis prefix - EXPECT_NE(0x54, its_configuration->get_diagnosis_address()); - EXPECT_EQ(0x55, its_configuration->get_diagnosis_address()); - EXPECT_NE(0x56, its_configuration->get_diagnosis_address()); - - // 4. Check logging - bool has_console = its_configuration->has_console_log(); - bool has_file = its_configuration->has_file_log(); - bool has_dlt = its_configuration->has_dlt_log(); - std::string logfile = its_configuration->get_logfile(); - vsomeip::logger::level_e loglevel - = its_configuration->get_loglevel(); - bool has_version_logging = its_configuration->log_version(); - std::uint32_t version_logging_interval = its_configuration->get_log_version_interval(); - - EXPECT_TRUE(check(has_console, _expected_has_console, "HAS CONSOLE")); - EXPECT_TRUE(check(has_file, _expected_has_file, "HAS FILE")); - EXPECT_TRUE(check(has_dlt, _expected_has_dlt, "HAS DLT")); - EXPECT_TRUE(check(logfile, _expected_logfile, "LOGFILE")); - EXPECT_TRUE(check(loglevel_to_string(loglevel), - _expected_loglevel, "LOGLEVEL")); - EXPECT_TRUE(check(has_version_logging, _expected_version_logging_enabled, - "VERSION LOGGING")); - EXPECT_TRUE(check(version_logging_interval, - _expected_version_logging_interval, - "VERSION LOGGING INTERVAL")); - - // watchdog - EXPECT_TRUE(its_configuration->is_watchdog_enabled()); - EXPECT_EQ(1234u, its_configuration->get_watchdog_timeout()); - EXPECT_EQ(7u, its_configuration->get_allowed_missing_pongs()); - - // file permissions - EXPECT_EQ(0444u, its_configuration->get_permissions_shm()); - EXPECT_EQ(0222u, its_configuration->get_permissions_uds()); - - // selective broadcasts - EXPECT_TRUE(its_configuration->supports_selective_broadcasts( - boost::asio::ip::address::from_string("160.160.160.160"))); - - // tracing - std::shared_ptr its_trace = its_configuration->get_trace(); - EXPECT_TRUE(its_trace->is_enabled_); - EXPECT_TRUE(its_trace->is_sd_enabled_); - EXPECT_EQ(4u, its_trace->channels_.size()); - EXPECT_TRUE(its_trace->filters_.size() == 2u || its_trace->filters_.size() == 4u); - for (const auto &c : its_trace->channels_) { - EXPECT_TRUE(c->name_ == std::string("testname") || c->name_ == std::string("testname2") || - c->name_ == std::string("testname3") || c->name_ == std::string("testname4")); - if (c->name_ == std::string("testname")) { - EXPECT_EQ(std::string("testid"), c->id_); - } else if (c->name_ == std::string("testname2")) { - EXPECT_EQ(std::string("testid2"), c->id_); - } else if (c->name_ == std::string("testname3")) { - EXPECT_EQ(std::string("testid3"), c->id_); - } else if (c->name_ == std::string("testname4")) { - EXPECT_EQ(std::string("testid4"), c->id_); - } - } - for (const auto &f : its_trace->filters_) { - auto its_channel_name = f->channels_.front(); - auto its_matches = f->matches_; - EXPECT_TRUE(its_channel_name == std::string("testname") || its_channel_name == std::string("testname2") || - its_channel_name == std::string("testname3") || its_channel_name == std::string("testname4")); - if (its_channel_name == std::string("testname")) { - EXPECT_EQ(2u, its_matches.size()); - - for (const vsomeip::trace::match_t m : its_matches) { - EXPECT_TRUE(std::get<0>(m) == vsomeip::service_t(0x1111) || - std::get<0>(m) == vsomeip::service_t(2222)); - EXPECT_TRUE(std::get<1>(m) == vsomeip::instance_t(0xffff)); - EXPECT_TRUE(std::get<2>(m) == vsomeip::method_t(0xffff)); - EXPECT_TRUE(f->is_positive_); - EXPECT_FALSE(f->is_range_); - } - } else if (its_channel_name == std::string("testname2")) { - EXPECT_EQ(2u, its_matches.size()); - - for (const vsomeip::trace::match_t m : its_matches) { - EXPECT_TRUE(std::get<0>(m) == vsomeip::service_t(0x3333) || - std::get<0>(m) == vsomeip::service_t(4444)); - EXPECT_TRUE(std::get<1>(m) == vsomeip::instance_t(0xffff)); - EXPECT_TRUE(std::get<2>(m) == vsomeip::method_t(0xffff)); - EXPECT_FALSE(f->is_positive_); - EXPECT_FALSE(f->is_range_); - } - } else if (its_channel_name == std::string("testname3")) { - EXPECT_EQ(2u, its_matches.size()); - - for (const vsomeip::trace::match_t m : its_matches) { - EXPECT_TRUE(std::get<0>(m) == vsomeip::service_t(0x1111) || - std::get<0>(m) == vsomeip::service_t(0x3333)); - EXPECT_TRUE(std::get<1>(m) == vsomeip::instance_t(0xffff)); - EXPECT_TRUE(std::get<2>(m) == vsomeip::method_t(0xffff) || - std::get<2>(m) == vsomeip::method_t(0x8888)); - EXPECT_FALSE(f->is_positive_); - EXPECT_FALSE(f->is_range_); - } - } else if (its_channel_name == std::string("testname4")) { - EXPECT_EQ(2u, its_matches.size()); - - for (const vsomeip::trace::match_t m : its_matches) { - EXPECT_TRUE(std::get<0>(m) == vsomeip::service_t(0x1111) || - std::get<0>(m) == vsomeip::service_t(0x3333)); - EXPECT_TRUE(std::get<1>(m) == vsomeip::instance_t(0x0001)); - EXPECT_TRUE(std::get<2>(m) == vsomeip::method_t(0xffff) || - std::get<2>(m) == vsomeip::method_t(0x8888)); - EXPECT_FALSE(f->is_positive_); - EXPECT_TRUE(f->is_range_); - } - } - } - - // Applications - std::size_t max_dispatchers = its_configuration->get_max_dispatchers( - EXPECTED_ROUTING_MANAGER_HOST); - std::size_t max_dispatch_time = its_configuration->get_max_dispatch_time( - EXPECTED_ROUTING_MANAGER_HOST); - std::size_t io_threads = its_configuration->get_io_thread_count( - EXPECTED_ROUTING_MANAGER_HOST); - std::size_t request_time = its_configuration->get_request_debouncing( - EXPECTED_ROUTING_MANAGER_HOST); - - EXPECT_TRUE(check(max_dispatchers, - _expected_application_max_dispatcher, "MAX DISPATCHERS")); - EXPECT_TRUE(check(max_dispatch_time, - _expected_application_max_dispatch_time, "MAX DISPATCH TIME")); - EXPECT_TRUE(check(io_threads, _expected_application_threads, - "IO THREADS")); - EXPECT_TRUE(check(request_time, - _expected_application_request_debounce_time, "REQUEST DEBOUNCE TIME")); - - EXPECT_EQ(0x9933, its_configuration->get_id("other_application")); - - std::map> its_plugins = - its_configuration->get_plugins(EXPECTED_ROUTING_MANAGER_HOST); - EXPECT_EQ(1u, its_plugins.size()); - for (const auto& plugin : its_plugins) { - EXPECT_EQ(vsomeip::plugin_type_e::APPLICATION_PLUGIN, plugin.first); - for (const auto& its_library : plugin.second) - EXPECT_EQ(std::string("libtestlibraryname.so." + std::to_string(VSOMEIP_APPLICATION_PLUGIN_VERSION)), its_library); - } - EXPECT_EQ(vsomeip::plugin_type_e::CONFIGURATION_PLUGIN, its_plugin->get_plugin_type()); - EXPECT_EQ("vsomeip-configuration-plugin", its_plugin->get_plugin_name()); - EXPECT_EQ(1u, its_plugin->get_plugin_version()); - - - // 5. Services - std::string its_unicast_address - = its_configuration->get_unicast_address(0x1234, 0x0022); - uint16_t its_reliable_port - = its_configuration->get_reliable_port(0x1234, 0x0022); - uint16_t its_unreliable_port - = its_configuration->get_unreliable_port(0x1234, 0x0022); - - EXPECT_TRUE(check(its_unicast_address, - _expected_unicast_address_1234_0022, - "UNICAST_ADDRESS_1234_0022")); - EXPECT_TRUE(check(its_reliable_port, - _expected_reliable_port_1234_0022, - "RELIABLE_PORT_1234_0022")); - EXPECT_TRUE(check(its_unreliable_port, - _expected_unreliable_port_1234_0022, - "UNRELIABLE_PORT_1234_0022")); - - its_unicast_address - = its_configuration->get_unicast_address(0x1234, 0x0023); - its_reliable_port - = its_configuration->get_reliable_port(0x1234, 0x0023); - its_unreliable_port - = its_configuration->get_unreliable_port(0x1234, 0x0023); - - EXPECT_TRUE(check(its_unicast_address, - _expected_unicast_address_1234_0023, - "UNICAST_ADDRESS_1234_0023")); - EXPECT_TRUE(check(its_reliable_port, - _expected_reliable_port_1234_0023, - "RELIABLE_PORT_1234_0023")); - EXPECT_TRUE(check(its_unreliable_port, - _expected_unreliable_port_1234_0023, - "UNRELIABLE_PORT_1234_0023")); - - its_unicast_address - = its_configuration->get_unicast_address(0x2277, 0x0022); - its_reliable_port - = its_configuration->get_reliable_port(0x2277, 0x0022); - its_unreliable_port - = its_configuration->get_unreliable_port(0x2277, 0x0022); - - EXPECT_TRUE(check(its_unicast_address, - _expected_unicast_address_2277_0022, - "UNICAST_ADDRESS_2277_0022")); - EXPECT_TRUE(check(its_reliable_port, - _expected_reliable_port_2277_0022, - "RELIABLE_PORT_2277_0022")); - EXPECT_TRUE(check(its_unreliable_port, - _expected_unreliable_port_2277_0022, - "UNRELIABLE_PORT_2277_0022")); - - its_unicast_address - = its_configuration->get_unicast_address(0x2266, 0x0022); - its_reliable_port - = its_configuration->get_reliable_port(0x2266, 0x0022); - its_unreliable_port - = its_configuration->get_unreliable_port(0x2266, 0x0022); - - EXPECT_TRUE(check(its_unicast_address, - _expected_unicast_address_2266_0022, - "UNICAST_ADDRESS_2266_0022")); - EXPECT_TRUE(check(its_reliable_port, - _expected_reliable_port_2266_0022, - "RELIABLE_PORT_2266_0022")); - EXPECT_TRUE(check(its_unreliable_port, - _expected_unreliable_port_2266_0022, - "UNRELIABLE_PORT_2266_0022")); - - its_unicast_address - = its_configuration->get_unicast_address(0x4466, 0x0321); - its_reliable_port - = its_configuration->get_reliable_port(0x4466, 0x0321); - its_unreliable_port - = its_configuration->get_unreliable_port(0x4466, 0x0321); - - EXPECT_TRUE(check(its_unicast_address, - _expected_unicast_address_4466_0321, - "UNICAST_ADDRESS_4466_0321")); - EXPECT_TRUE(check(its_reliable_port, - _expected_reliable_port_4466_0321, - "RELIABLE_PORT_4466_0321")); - EXPECT_TRUE(check(its_unreliable_port, - _expected_unreliable_port_4466_0321, - "UNRELIABLE_PORT_4466_0321")); - - std::string its_multicast_address; - std::uint16_t its_multicast_port; - its_configuration->get_multicast(0x7809, 0x1, 0x1111, - its_multicast_address, its_multicast_port); - EXPECT_EQ(1234u, its_multicast_port); - EXPECT_EQ(std::string("224.212.244.225"), its_multicast_address); - EXPECT_EQ(8u, its_configuration->get_threshold(0x7809, 0x1, 0x1111)); - - EXPECT_TRUE(its_configuration->is_offered_remote(0x1234,0x0022)); - EXPECT_FALSE(its_configuration->is_offered_remote(0x3333,0x1)); - - EXPECT_TRUE(its_configuration->has_enabled_magic_cookies("10.0.2.15", 30506)); - EXPECT_FALSE(its_configuration->has_enabled_magic_cookies("10.0.2.15", 30503)); - - std::set> its_remote_services = - its_configuration->get_remote_services(); - EXPECT_EQ(1u, its_remote_services.size()); - for (const auto &p : its_remote_services) { - EXPECT_EQ(0x4466, p.first); - EXPECT_EQ(0x321, p.second); - } - - EXPECT_TRUE(its_configuration->is_someip(0x3333,0x1)); - EXPECT_FALSE(its_configuration->is_someip(0x3555,0x1)); - - // Internal services - EXPECT_TRUE(its_configuration->is_local_service(0x1234, 0x0022)); - EXPECT_TRUE(its_configuration->is_local_service(0x3333,0x1)); - // defined range, service level only - EXPECT_FALSE(its_configuration->is_local_service(0xF0FF,0x1)); - EXPECT_TRUE(its_configuration->is_local_service(0xF100,0x1)); - EXPECT_TRUE(its_configuration->is_local_service(0xF101,0x23)); - EXPECT_TRUE(its_configuration->is_local_service(0xF109,0xFFFF)); - EXPECT_FALSE(its_configuration->is_local_service(0xF10a,0x1)); - // defined range, service and instance level - EXPECT_FALSE(its_configuration->is_local_service(0xF2FF,0xFFFF)); - EXPECT_TRUE(its_configuration->is_local_service(0xF300,0x1)); - EXPECT_TRUE(its_configuration->is_local_service(0xF300,0x5)); - EXPECT_TRUE(its_configuration->is_local_service(0xF300,0x10)); - EXPECT_FALSE(its_configuration->is_local_service(0xF300,0x11)); - EXPECT_FALSE(its_configuration->is_local_service(0xF301,0x11)); - - // clients - std::map> used_ports; - used_ports[true].insert(0x11); - used_ports[false].insert(0x10); - std::uint16_t port_to_use(0x0); - EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x1, vsomeip::ILLEGAL_PORT, true, used_ports, port_to_use)); - EXPECT_EQ(0x10, port_to_use); - EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x1, vsomeip::ILLEGAL_PORT, false, used_ports, port_to_use)); - EXPECT_EQ(0x11, port_to_use); - - used_ports[true].insert(0x10); - used_ports[false].insert(0x11); - EXPECT_FALSE(its_configuration->get_client_port(0x8888, 0x1, vsomeip::ILLEGAL_PORT, true, used_ports, port_to_use)); - EXPECT_EQ(vsomeip::ILLEGAL_PORT, port_to_use); - EXPECT_FALSE(its_configuration->get_client_port(0x8888, 0x1, vsomeip::ILLEGAL_PORT, false, used_ports, port_to_use)); - EXPECT_EQ(vsomeip::ILLEGAL_PORT, port_to_use); - - - //check for correct client port assignment if service / instance was not configured but a remote port range - used_ports.clear(); - EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x12, 0x7725, true, used_ports, port_to_use)); - EXPECT_EQ(0x771B, port_to_use); - used_ports[true].insert(0x771B); - EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x12, 0x7725, true, used_ports, port_to_use)); - EXPECT_EQ(0x771C, port_to_use); - used_ports[true].insert(0x771C); - EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x12, 0x7B0D, true, used_ports, port_to_use)); - EXPECT_EQ(0x7B03, port_to_use); - used_ports[true].insert(0x7B03); - EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x12, 0x7B0D, true, used_ports, port_to_use)); - EXPECT_EQ(0x7B04, port_to_use); - used_ports[true].insert(0x7B04); - EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x12, 0x7EF4, true, used_ports, port_to_use)); - EXPECT_EQ(0x7EEB, port_to_use); - used_ports[true].insert(0x7EEB); - EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x12, 0x7EF4, true, used_ports, port_to_use)); - EXPECT_EQ(0x7EEC, port_to_use); - used_ports[true].insert(0x7EEC); - used_ports.clear(); - - - // payload sizes - // use 17000 instead of 1500 as configured max-local-payload size will be - // increased to bigger max-reliable-payload-size - std::uint32_t max_local_message_size( - 17000u + 16u + + VSOMEIP_SEND_COMMAND_SIZE); - EXPECT_EQ(max_local_message_size, its_configuration->get_max_message_size_local()); - EXPECT_EQ(11u, its_configuration->get_buffer_shrink_threshold()); - EXPECT_EQ(14999u + 16u, its_configuration->get_max_message_size_reliable("10.10.10.10", 7777)); - EXPECT_EQ(17000u + 16, its_configuration->get_max_message_size_reliable("11.11.11.11", 4711)); - EXPECT_EQ(15001u + 16, its_configuration->get_max_message_size_reliable("10.10.10.11", 7778)); - - // security - EXPECT_TRUE(its_configuration->check_routing_credentials(0x7788, 0x123, 0x456)); - - // GID does not match - EXPECT_FALSE(its_configuration->check_routing_credentials(0x7788, 0x123, 0x222)); - - // UID does not match - EXPECT_FALSE(its_configuration->check_routing_credentials(0x7788, 0x333, 0x456)); - - // client is not the routing manager - EXPECT_TRUE(its_configuration->check_routing_credentials(0x7777, 0x888, 0x999)); - - auto its_security = vsomeip::security_impl::get(); - EXPECT_TRUE(its_security->is_enabled()); - EXPECT_TRUE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1234, 0x5678)); - EXPECT_TRUE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1235, 0x5678)); - EXPECT_TRUE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1236, 0x5678)); - EXPECT_TRUE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1236, 0x5676)); - - EXPECT_FALSE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1236, 0x5679)); - EXPECT_FALSE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1234, 0x5679)); - EXPECT_FALSE(its_security->is_offer_allowed(1000, 1000, 0x1277, 0x1233, 0x5679)); - EXPECT_FALSE(its_security->is_offer_allowed(1001, 1001, 0x1266, 0x1233, 0x5679)); - // explicitly denied offers - EXPECT_FALSE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1234, 0x5678)); - EXPECT_FALSE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1235, 0x5678)); - EXPECT_TRUE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1234, 0x5679)); - EXPECT_TRUE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1300, 0x1)); - EXPECT_TRUE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1300, 0x2)); - EXPECT_FALSE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1236, 0x5678)); - EXPECT_FALSE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1236, 0x5675)); - EXPECT_FALSE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1236, 0x5676)); - EXPECT_FALSE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1236, 0x5677)); - EXPECT_TRUE(its_security->is_offer_allowed(4000, 4000, 0x1443, 0x1236, 0x5679)); - - // explicitly allowed requests of methods / events - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5678, 0x0001)); - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5678, 0x8002)); - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1346, 0x1234, 0x5688, 0x8002)); - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5699, 0x8006)); - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5699, 0x8001)); - - EXPECT_FALSE(its_security->is_client_allowed(2001, 2001, 0x1347, 0x1234, 0x5678, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(2001, 2001, 0x1342, 0x1234, 0x5678, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5677, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5700, 0x0001)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5699, 0x8007)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1234, 0x5700, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1230, 0x5678, 0x0001)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1230, 0x5678, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(4000, 4000, 0x1443, 0x1234, 0x5678, 0x0002)); - EXPECT_FALSE(its_security->is_client_allowed(4000, 4000, 0x1446, 0x1234, 0x5678, 0xFFFF)); - EXPECT_TRUE(its_security->is_client_allowed(4000, 4000, 0x1443, 0x1234, 0x5679, 0x0003)); - EXPECT_FALSE(its_security->is_client_allowed(4000, 4000, 0x1443, 0x1234, 0x5679, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(4000, 4000, 0x1443, 0x1234, 0x5699, 0x9001)); - EXPECT_FALSE(its_security->is_client_allowed(4000, 4000, 0x1443, 0x1234, 0x5699, 0x9006)); - EXPECT_FALSE(its_security->is_client_allowed(4001, 4001, 0x1442, 0x1234, 0x5678, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(4001, 4001, 0x1447, 0x1234, 0x5678, 0xFFFF)); - - // check that any method ID is allowed - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1237, 0x5678, 0x0001)); - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1237, 0x5678, 0xFFFF)); - - // check that any instance ID is allowed but only one method ID - EXPECT_TRUE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1238, 0x0004, 0x0001)); - EXPECT_FALSE(its_security->is_client_allowed(2000, 2000, 0x1343, 0x1238, 0x0004, 0x0002)); - - // DENY NOTHING policy - // check that ANY_METHOD is allowed in a "deny nothing" policy - EXPECT_TRUE(its_security->is_client_allowed(5000, 5000, 0x1550, 0x1234, 0x5678, 0xFFFF)); - // check that specific method ID is allowed in a "deny nothing" policy - EXPECT_TRUE(its_security->is_client_allowed(5000, 5000, 0x1550, 0x1234, 0x5678, 0x0001)); - - // ALLOW NOTHING policy - // check that ANY_METHOD is denied in a "allow nothing" policy - EXPECT_FALSE(its_security->is_client_allowed(6000, 6000, 0x1660, 0x1234, 0x5678, 0xFFFF)); - // check that specific method ID is denied in a "allow nothing" policy - EXPECT_FALSE(its_security->is_client_allowed(6000, 6000, 0x1660, 0x1234, 0x5678, 0x0001)); - - // DENY only one service instance and ANY_METHOD (0x01 - 0xFFFF) policy - EXPECT_FALSE(its_security->is_client_allowed(7000, 7000, 0x1770, 0x1234, 0x5678, 0xFFFF)); - EXPECT_FALSE(its_security->is_client_allowed(7000, 7000, 0x1770, 0x1234, 0x5678, 0x0001)); - - // allow only one service instance and ANY_METHOD policy - EXPECT_TRUE(its_security->is_client_allowed(8000, 8000, 0x1880, 0x1234, 0x5678, 0xFFFF)); - EXPECT_TRUE(its_security->is_client_allowed(8000, 8000, 0x1880, 0x1234, 0x5678, 0x0001)); - - // check request service - EXPECT_TRUE(its_security->is_client_allowed(5000, 5000, 0x1550, 0x1234, 0x5678, 0x00, true)); - EXPECT_FALSE(its_security->is_client_allowed(6000, 6000, 0x1660, 0x1234, 0x5678, 0x00, true)); - EXPECT_FALSE(its_security->is_client_allowed(7000, 7000, 0x1770, 0x1234, 0x5678, 0x00, true)); - EXPECT_TRUE(its_security->is_client_allowed(7000, 7000, 0x1770, 0x2222, 0x5678, 0x00, true)); - EXPECT_TRUE(its_security->is_client_allowed(8000, 8000, 0x1880, 0x1234, 0x5678, 0x00, true)); - - EXPECT_TRUE(its_security->check_credentials(0x1277, 1000, 1000)); - EXPECT_FALSE(its_security->check_credentials(0x1277, 1001, 1001)); - EXPECT_TRUE(its_security->check_credentials(0x1278, 1000, 1000)); - EXPECT_TRUE(its_security->check_credentials(0x1278, 9000, 9000)); - - // Security update / removal whitelist - EXPECT_TRUE(its_security->is_policy_removal_allowed(1000)); - EXPECT_TRUE(its_security->is_policy_removal_allowed(1001)); - EXPECT_TRUE(its_security->is_policy_removal_allowed(1008)); - EXPECT_TRUE(its_security->is_policy_removal_allowed(2000)); - EXPECT_TRUE(its_security->is_policy_removal_allowed(3000)); - - EXPECT_FALSE(its_security->is_policy_removal_allowed(2001)); - EXPECT_FALSE(its_security->is_policy_removal_allowed(3001)); - - // create a valid policy object that is on whitelist and test is_policy_update_allowed method - std::shared_ptr _policy(std::make_shared()); - uint32_t its_uid = 1000; - uint32_t its_gid = 1000; - - // policy elements - boost::icl::discrete_interval its_uids(its_uid, its_uid); - boost::icl::interval_set its_gids; - its_gids.insert(boost::icl::interval::closed(its_gid, its_gid)); - - _policy->credentials_ += std::make_pair(its_uids, its_gids); - _policy->allow_who_ = true; - _policy->allow_what_ = true; - - vsomeip::service_t its_service(0x1234); - - boost::icl::discrete_interval its_instances(0x1, 0x2); - boost::icl::interval_set its_methods; - its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); - boost::icl::interval_map > its_instances_methods; - its_instances_methods += std::make_pair(its_instances, its_methods); - - _policy->requests_ += std::make_pair( - boost::icl::discrete_interval( - its_service, its_service, - boost::icl::interval_bounds::closed()), - its_instances_methods); - EXPECT_TRUE(its_security->is_policy_update_allowed(1000, _policy)); - - // test valid policy that holds a single service id which is whitelisted - vsomeip::service_t its_second_service(0x7800); - _policy->requests_ += std::make_pair( - boost::icl::discrete_interval( - its_second_service, its_second_service, - boost::icl::interval_bounds::closed()), - its_instances_methods); - EXPECT_TRUE(its_security->is_policy_update_allowed(1000, _policy)); - - // test invalid UID which is not whitelisted - EXPECT_FALSE(its_security->is_policy_update_allowed(2002, _policy)); - - // test invalid policy that additionally holds a service id which is not whitelisted - vsomeip::service_t its_third_service(0x8888); - _policy->requests_ += std::make_pair( - boost::icl::discrete_interval( - its_third_service, its_third_service, - boost::icl::interval_bounds::closed()), - its_instances_methods); - EXPECT_FALSE(its_security->is_policy_update_allowed(1000, _policy)); - - // TCP connection setting: - // max TCP connect time / max allowed number of aborted TCP endpoint restarts until forced restart - EXPECT_EQ(its_configuration->get_max_tcp_connect_time(), 10000u); - EXPECT_EQ(its_configuration->get_max_tcp_restart_aborts(), 15u); - - // 6. Service discovery - bool enabled = its_configuration->is_sd_enabled(); - std::string protocol = its_configuration->get_sd_protocol(); - uint16_t port = its_configuration->get_sd_port(); - std::string multicast = its_configuration->get_sd_multicast(); - - uint32_t initial_delay_min = its_configuration->get_sd_initial_delay_min(); - uint32_t initial_delay_max = its_configuration->get_sd_initial_delay_max(); - int32_t repetitions_base_delay = its_configuration->get_sd_repetitions_base_delay(); - uint8_t repetitions_max = its_configuration->get_sd_repetitions_max(); - vsomeip::ttl_t ttl = its_configuration->get_sd_ttl(); - int32_t cyclic_offer_delay = its_configuration->get_sd_cyclic_offer_delay(); - int32_t request_response_delay = its_configuration->get_sd_request_response_delay(); - - EXPECT_TRUE(check(enabled, _expected_enabled, "SD ENABLED")); - EXPECT_TRUE(check(protocol, _expected_protocol, "SD PROTOCOL")); - EXPECT_TRUE(check(multicast, _expected_multicast, "SD MULTICAST")); - EXPECT_TRUE(check(port, _expected_port, "SD PORT")); - - EXPECT_TRUE(check(initial_delay_min, _expected_initial_delay_min, "SD INITIAL DELAY MIN")); - EXPECT_TRUE(check(initial_delay_max, _expected_initial_delay_max, "SD INITIAL DELAY MAX")); - EXPECT_TRUE(check(repetitions_base_delay, _expected_repetitions_base_delay, "SD REPETITION BASE DELAY")); - EXPECT_TRUE(check(repetitions_max,_expected_repetitions_max, "SD REPETITION MAX")); - EXPECT_TRUE(check(ttl, _expected_ttl, "SD TTL")); - EXPECT_TRUE(check(cyclic_offer_delay, static_cast(_expected_cyclic_offer_delay), "SD CYCLIC OFFER DELAY")); - EXPECT_TRUE(check(request_response_delay, static_cast(_expected_request_response_delay), "SD RESPONSE REQUEST DELAY")); - EXPECT_EQ(1000u, its_configuration->get_sd_offer_debounce_time()); - - ASSERT_TRUE(vsomeip::plugin_manager_impl::get()->unload_plugin(vsomeip::plugin_type_e::CONFIGURATION_PLUGIN)); -} - -TEST(configuration_test, check_config_file) { - // Check current configuration file format - check_file(CONFIGURATION_FILE, - EXPECTED_UNICAST_ADDRESS, - EXPECTED_HAS_CONSOLE, - EXPECTED_HAS_FILE, - EXPECTED_HAS_DLT, - EXPECTED_VERSION_LOGGING_ENABLED, - EXPECTED_VERSION_LOGGING_INTERVAL, - EXPECTED_APPLICATION_MAX_DISPATCHERS, - EXPECTED_APPLICATION_MAX_DISPATCH_TIME, - EXPECTED_APPLICATION_THREADS, - EXPECTED_APPLICATION_REQUEST_DEBOUNCE_TIME, - EXPECTED_LOGFILE, - EXPECTED_LOGLEVEL, - EXPECTED_UNICAST_ADDRESS_1234_0022, - EXPECTED_RELIABLE_PORT_1234_0022, - EXPECTED_UNRELIABLE_PORT_1234_0022, - EXPECTED_UNICAST_ADDRESS_1234_0023, - EXPECTED_RELIABLE_PORT_1234_0023, - EXPECTED_UNRELIABLE_PORT_1234_0023, - EXPECTED_UNICAST_ADDRESS_2277_0022, - EXPECTED_RELIABLE_PORT_2277_0022, - EXPECTED_UNRELIABLE_PORT_2277_0022, - EXPECTED_UNICAST_ADDRESS_2266_0022, - EXPECTED_RELIABLE_PORT_2266_0022, - EXPECTED_UNRELIABLE_PORT_2266_0022, - EXPECTED_UNICAST_ADDRESS_4466_0321, - EXPECTED_RELIABLE_PORT_4466_0321, - EXPECTED_UNRELIABLE_PORT_4466_0321, - EXPECTED_SD_ENABLED, - EXPECTED_SD_PROTOCOL, - EXPECTED_SD_MULTICAST, - EXPECTED_SD_PORT, - EXPECTED_INITIAL_DELAY_MIN, - EXPECTED_INITIAL_DELAY_MAX, - EXPECTED_REPETITIONS_BASE_DELAY, - EXPECTED_REPETITIONS_MAX, - EXPECTED_TTL, - EXPECTED_CYCLIC_OFFER_DELAY, - EXPECTED_REQUEST_RESPONSE_DELAY); -} - -TEST(configuration_test, check_deprecated_config_file) { - // Check deprecated configuration file format - check_file(DEPRECATED_CONFIGURATION_FILE, - EXPECTED_UNICAST_ADDRESS, - EXPECTED_HAS_CONSOLE, - EXPECTED_HAS_FILE, - EXPECTED_HAS_DLT, - EXPECTED_VERSION_LOGGING_ENABLED, - EXPECTED_VERSION_LOGGING_INTERVAL, - EXPECTED_APPLICATION_MAX_DISPATCHERS, - EXPECTED_APPLICATION_MAX_DISPATCH_TIME, - EXPECTED_APPLICATION_THREADS, - EXPECTED_APPLICATION_REQUEST_DEBOUNCE_TIME, - EXPECTED_LOGFILE, - EXPECTED_LOGLEVEL, - EXPECTED_UNICAST_ADDRESS_1234_0022, - EXPECTED_RELIABLE_PORT_1234_0022, - EXPECTED_UNRELIABLE_PORT_1234_0022, - EXPECTED_UNICAST_ADDRESS_1234_0023, - EXPECTED_RELIABLE_PORT_1234_0023, - EXPECTED_UNRELIABLE_PORT_1234_0023, - EXPECTED_UNICAST_ADDRESS_2277_0022, - EXPECTED_RELIABLE_PORT_2277_0022, - EXPECTED_UNRELIABLE_PORT_2277_0022, - EXPECTED_UNICAST_ADDRESS_2266_0022, - EXPECTED_RELIABLE_PORT_2266_0022, - EXPECTED_UNRELIABLE_PORT_2266_0022, - EXPECTED_UNICAST_ADDRESS_4466_0321, - EXPECTED_RELIABLE_PORT_4466_0321, - EXPECTED_UNRELIABLE_PORT_4466_0321, - EXPECTED_SD_ENABLED, - EXPECTED_SD_PROTOCOL, - EXPECTED_SD_MULTICAST, - EXPECTED_SD_PORT, - EXPECTED_DEPRECATED_INITIAL_DELAY_MIN, - EXPECTED_DEPRECATED_INITIAL_DELAY_MAX, - EXPECTED_DEPRECATED_REPETITIONS_BASE_DELAY, - EXPECTED_DEPRECATED_REPETITIONS_MAX, - EXPECTED_DEPRECATED_TTL, - EXPECTED_CYCLIC_OFFER_DELAY, - EXPECTED_DEPRECATED_REQUEST_RESPONSE_DELAY); -} - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/configuration_tests/configuration-test.json b/test/configuration_tests/configuration-test.json deleted file mode 100644 index e18026e..0000000 --- a/test/configuration_tests/configuration-test.json +++ /dev/null @@ -1,492 +0,0 @@ -{ - "unicast" : "10.0.2.15", - "diagnosis" : "0x55", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : { "enable" : "true", "path" : "/home/someip/another-file.log" }, - "dlt" : "false", - "version" : { - "enable" : "false", - "interval" : "15" - } - }, - "watchdog" : - { - "enable" : "true", - "timeout" : "1234", - "allowed_missing_pongs" : "7" - }, - "file-permissions" : - { - "permissions-shm" : "0444", - "permissions-uds" : "0222" - }, - "supports_selective_broadcasts" : - [ - "160.160.160.160" - ], - "tracing" : - { - "enable" : "true", - "sd_enable" : "true", - "channels" : - [ - { - "name" : "testname", - "id" : "testid" - }, - { - "name" : "testname2", - "id" : "testid2" - }, - { - "name" : "testname3", - "id" : "testid3" - }, - { - "name" : "testname4", - "id" : "testid4" - } - ], - "filters" : - [ - { - "channel" : "testname", - "matches" : [ "0x1111", 2222 ], - "type" : "positive" - }, - { - "channel" : "testname2", - "matches" : [ "0x3333", 4444 ], - "type" : "negative" - }, - { - "channel" : "testname3", - "matches" : [ "0x1111", { "service" : "0x3333", "instance" : "0xffff", "method" : "0x8888" } ], - "type" : "negative" - }, - { - "channel" : "testname4", - "matches" : - { - "from" : - { - "service" : "0x1111", - "instance" : "0x0001", - "method" : "0xffff" - }, - "to" : - { - "service" : "0x3333", - "instance" : "0x0001", - "method" : "0x8888" - } - }, - "type" : "negative" - } - ] - }, - "applications" : - [ - { - "name" : "my_application", - "id" : "0x7788", - "max_dispatchers" : "25", - "max_dispatch_time" : "1234", - "threads" : "12", - "request_debounce_time" : "5000", - "plugins" : - [ - { - "name" : "testlibraryname", - "type" : "application_plugin" - }, - { - "name" : "wrongtestlibraryname", - "type" : "intentionally_wrong_plugin" - } - ] - }, - { - "name" : "other_application", - "id" : "0x9933", - "threads" : "0", - "threads" : "256", - "request_debounce_time" : "10001" - } - ], - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x0022", - "unicast" : "local", - "reliable" : { "port" : "30506", "enable-magic-cookies" : "true" }, - "unreliable" : "31000", - "events" : - [ - { - "event" : "0x0778", - "is_field" : "false" - }, - { - "event" : "0x779", - "is_field" : "true" - }, - { - "event" : "0x77A", - "is_field" : "false" - } - ], - "eventgroups" : - [ - { - "eventgroup" : "0x4567", - "multicast" : "225.226.227.228", - "events" : [ "0x778", "0x779" ] - }, - { - "eventgroup" : "0x4569", - "multicast" : "225.227.227.228", - "events" : [ "0x779", "0x77A" ] - }, - { - "eventgroup" : "0x4569", - "multicast" : "225.222.227.228", - "events" : [ "0x778", "0x77A" ] - } - ] - }, - { - "service" : "0x1234", - "instance" : "0x0023", - "reliable" : "30503" - }, - { - "service" : "0x2277", - "instance" : "0x0022", - "reliable" : { "port" : "30505" }, - "unreliable" : "31001" - }, - { - "service" : "0x2266", - "instance" : "0x0022", - "reliable" : "30505", - "unreliable" : "30507" - }, - { - "service" : "0x4466", - "instance" : "0x0321", - "unicast" : "10.0.2.23", - "reliable" : "30506", - "unreliable" : "30444" - }, - { - "service" : "0x3333", - "instance" : "0x1" - }, - { - "service" : "0x7809", - "instance" : "0x1", - "multicast" : - { - "address" : "224.212.244.225", - "port" : "1234" - }, - "eventgroups" : - [ - { - "eventgroup" : "0x1111", - "threshold" : "8", - "is_multicast" : "true", - "events" : [ "0x778", "0x77A" ] - } - ] - }, - { - "service" : "0x3555", - "instance" : "0x1", - "protocol" : "other" - } - ], - "internal_services" : - [ - { - "first" : "0xF100", - "last" : "0xF109" - }, - { - "first" : { - "service" : "0xF300", - "instance" : "0x1" - }, - "last" : { - "service" : "0xF300", - "instance" : "0x10" - } - } - ], - "clients" : - [ - { - "reliable_remote_ports" : { "first" : "30500", "last" : "30599" }, - "unreliable_remote_ports" : { "first" : "30500", "last" : "30599" }, - "reliable_client_ports" : { "first" : "30491", "last" : "30499" }, - "unreliable_client_ports" : { "first" : "30491", "last" : "30499" } - }, - { - "reliable_remote_ports" : { "first" : "31500", "last" : "31599" }, - "unreliable_remote_ports" : { "first" : "31500", "last" : "31599" }, - "reliable_client_ports" : { "first" : "31491", "last" : "31499" }, - "unreliable_client_ports" : { "first" : "31491", "last" : "31499" } - }, - { - "reliable_remote_ports" : { "first" : "32500", "last" : "32599" }, - "unreliable_remote_ports" : { "first" : "32500", "last" : "32599" }, - "reliable_client_ports" : { "first" : "32491", "last" : "32499" }, - "unreliable_client_ports" : { "first" : "32491", "last" : "32499" } - }, - { - "service" : "0x8888", - "instance" : "0x1", - "unreliable" : [ "0x11", "0x10" ], - "reliable" : [ "0x11", "0x10" ] - }, - { - "service" : "8888", - "instance" : "1", - "unreliable" : [ 40000, 40001 ], - "reliable" : [ 40000, 40001 ] - } - ], - "tcp-restart-aborts-max" : "15", - "tcp-connect-time-max" : "10000", - "max-payload-size-local" : "15000", - "max-payload-size-reliable" : "17000", - "buffer-shrink-threshold" : "11", - "payload-sizes": - [ - { - "unicast":"10.10.10.10", - "ports": - [ - { - "port":"7777", - "max-payload-size":"14999" - } - ] - }, - { - "unicast":"10.10.10.11", - "ports": - [ - { - "port":"7778", - "max-payload-size":"15001" - } - ] - } - ], - "security" : - { - "check_credentials" : "true", - "policies" : - [ - { - "credentials" : { "uid" : "1000", "gid" : "1000" }, - "allow" : - { - "offers": - [ - { - "service" : "0x1234", - "instance" : "0x5678" - }, - { - "service" : "0x1235", - "instance" : "0x5678" - }, - { - "service" : "0x1236", - "instances" : [{ "first" : "0x5676", "last" : "0x5677"}, "0x5678"] - } - ] - } - }, - { - "credentials" : { "uid" : "2000", "gid" : "2000" }, - "allow" : - { - "requests": - [ - { - "service" : "0x1234", - "instances" : [ - { - "ids" : ["0x5678", { "first" : "0x5679", "last" : "0x5699"}], - "methods" : [ "0x0001", { "first" : "0x8001", "last" : "0x8006" }] - } - ] - }, - { - "service" : "0x1237", - "instances" : [ - { - "ids" : ["0x5678"], - "methods" : "any" - } - ] - }, - { - "service" : "0x1238", - "instances" : [ - { - "ids" : "any", - "methods" : ["0x0001"] - } - ] - } - ] - } - }, - { - "credentials" : { "uid" : "4000", "gid" : "4000" }, - "deny" : - { - "requests": - [ - { - "service" : "0x1234", - "instances" : [ - { - "ids" : ["0x5678", { "first" : "0x5679", "last" : "0x5699"}], - "methods" : [ "0x0002", { "first" : "0x9001", "last" : "0x9006" }] - } - ] - } - ], - "offers": - [ - { - "service" : "0x1234", - "instance" : "0x5678" - }, - { - "service" : "0x1235", - "instance" : "0x5678" - }, - { - "service" : "0x1236", - "instances" : [{ "first" : "0x5675", "last" : "0x5677"}, "0x5678"] - } - ] - } - }, - { - "credentials" : { "uid" : "5000", "gid" : "5000" }, - "deny" : - { - } - }, - { - "credentials" : { "uid" : "6000", "gid" : "6000" }, - "allow" : - { - } - }, - { - "credentials" : { "uid" : "7000", "gid" : "7000" }, - "deny" : - { - "requests": - [ - { - "service" : "0x1234", - "instances" : [ - { - "ids" : ["0x5678"], - "methods" : "any" - } - ] - } - ] - } - }, - { - "credentials" : { "uid" : "8000", "gid" : "8000" }, - "allow" : - { - "requests": - [ - { - "service" : "0x1234", - "instances" : [ - { - "ids" : ["0x5678"], - "methods" : "any" - } - ] - } - ] - } - }, - { - "credentials" : { - "allow": [ - { - "uid": [ - "9000" - ], - "gid": [ - "9000" - ] - } - ] - }, - "deny" : - { - } - } - ] - }, - "security-update-whitelist" : - { - "uids" : - [ - {"first" : "1000", "last" : "1008"}, - {"first" : "1100", "last" : "1200"}, - "2000", - "3000" - ], - "services" : - [ - {"first" : "0x1234", "last" : "0x1238"}, - {"first" : "0x2000", "last" : "0x2500"}, - "0x7800" - ], - "check-whitelist" : "true" - }, - "routing" : "my_application", - "routing-credentials" : - { - "uid" : "0x123", - "gid" : "0x456" - }, - "service-discovery" : - { - "enable" : "true", - "protocol" : "udp", - "multicast" : "224.212.244.223", - "port" : "30666", - "initial_delay_min" : "1234", - "initial_delay_max" : "2345", - "repetitions_base_delay" : "4242", - "repetitions_max" : "4", - "ttl" : "13", - "cyclic_offer_delay" : "2132", - "request_response_delay" : "1111", - "offer_debounce_time" : "1000" - } -} diff --git a/test/cpu_load_tests/conf/cpu_load_test_client_master.json.in b/test/cpu_load_tests/conf/cpu_load_test_client_master.json.in deleted file mode 100644 index ec9dcd7..0000000 --- a/test/cpu_load_tests/conf/cpu_load_test_client_master.json.in +++ /dev/null @@ -1,38 +0,0 @@ -{ - "unicast" : "@TEST_IP_MASTER@", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "false", - "path" : "/var/log/vsomeip.log" - }, - - "dlt" : "false" - }, - - "applications" : - [ - { - "name" : "cpu_load_test_client", - "id" : "0x2222" - } - ], - "npdu-default-timings" : { - "debounce-time-request" : "0", - "debounce-time-response" : "0", - "max-retention-time-request" : "0", - "max-retention-time-response" : "0" - }, - "routing" : "cpu_load_test_client", - "service-discovery" : - { - "enable" : "true", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp" - } -} diff --git a/test/cpu_load_tests/conf/cpu_load_test_client_slave.json.in b/test/cpu_load_tests/conf/cpu_load_test_client_slave.json.in deleted file mode 100644 index 4da82f4..0000000 --- a/test/cpu_load_tests/conf/cpu_load_test_client_slave.json.in +++ /dev/null @@ -1,38 +0,0 @@ -{ - "unicast" : "@TEST_IP_SLAVE@", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "false", - "path" : "/var/log/vsomeip.log" - }, - - "dlt" : "false" - }, - - "applications" : - [ - { - "name" : "cpu_load_test_client", - "id" : "0x2222" - } - ], - "npdu-default-timings" : { - "debounce-time-request" : "0", - "debounce-time-response" : "0", - "max-retention-time-request" : "0", - "max-retention-time-response" : "0" - }, - "routing" : "cpu_load_test_client", - "service-discovery" : - { - "enable" : "true", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp" - } -} diff --git a/test/cpu_load_tests/conf/cpu_load_test_service_master.json.in b/test/cpu_load_tests/conf/cpu_load_test_service_master.json.in deleted file mode 100644 index da34e22..0000000 --- a/test/cpu_load_tests/conf/cpu_load_test_service_master.json.in +++ /dev/null @@ -1,51 +0,0 @@ -{ - "unicast" : "@TEST_IP_MASTER@", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "false", - "path" : "/tmp/vsomeip.log" - }, - - "dlt" : "false" - }, - - "applications" : - [ - { - "name" : "cpu_load_test_service", - "id" : "0x1111" - } - ], - - "services" : - [ - { - "service" : "0x1111", - "instance" : "0x1", - "unreliable" : "30510", - "reliable" : - { - "port" : "30510", - "enable-magic-cookies" : "false" - } - } - ], - "npdu-default-timings" : { - "debounce-time-request" : "0", - "debounce-time-response" : "0", - "max-retention-time-request" : "0", - "max-retention-time-response" : "0" - }, - "routing" : "cpu_load_test_service", - "service-discovery" : - { - "enable" : "true", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp" - } -} diff --git a/test/cpu_load_tests/conf/cpu_load_test_service_slave.json.in b/test/cpu_load_tests/conf/cpu_load_test_service_slave.json.in deleted file mode 100644 index 389aea0..0000000 --- a/test/cpu_load_tests/conf/cpu_load_test_service_slave.json.in +++ /dev/null @@ -1,51 +0,0 @@ -{ - "unicast" : "@TEST_IP_SLAVE@", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "false", - "path" : "/tmp/vsomeip.log" - }, - - "dlt" : "false" - }, - - "applications" : - [ - { - "name" : "cpu_load_test_service", - "id" : "0x1111" - } - ], - - "services" : - [ - { - "service" : "0x1111", - "instance" : "0x1", - "unreliable" : "30510", - "reliable" : - { - "port" : "30510", - "enable-magic-cookies" : "false" - } - } - ], - "npdu-default-timings" : { - "debounce-time-request" : "0", - "debounce-time-response" : "0", - "max-retention-time-request" : "0", - "max-retention-time-response" : "0" - }, - "routing" : "cpu_load_test_service", - "service-discovery" : - { - "enable" : "true", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp" - } -} diff --git a/test/cpu_load_tests/cpu_load_measurer.cpp b/test/cpu_load_tests/cpu_load_measurer.cpp deleted file mode 100644 index d4360b3..0000000 --- a/test/cpu_load_tests/cpu_load_measurer.cpp +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "cpu_load_measurer.hpp" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -cpu_load_measurer::~cpu_load_measurer() { -} - -cpu_load_measurer::cpu_load_measurer(std::uint32_t _pid) : - pid_(_pid), - jiffies_complete_start_(0), - jiffies_idle_start_(0), - jiffies_complete_stop_(0), - jiffies_idle_stop_(0), - clock_ticks_(0), - jiffies_passed_pid_start_(0), - jiffies_passed_pid_stop_(0), - cpu_load_pid_(0.0), - cpu_load_overall_(0.0), - cpu_load_pid_wo_idle_(0.0) { -} - -void cpu_load_measurer::start() { - // reset everything - jiffies_complete_start_ = 0; - jiffies_idle_start_ = 0; - jiffies_complete_stop_ = 0; - jiffies_idle_stop_ = 0; - clock_ticks_ = 0; - jiffies_passed_pid_start_ = 0; - jiffies_passed_pid_stop_ = 0; - cpu_load_pid_= 0.0; - cpu_load_overall_ = 0.0; - cpu_load_pid_wo_idle_ = 0.0; - //start - jiffies_complete_start_ = read_proc_stat(&jiffies_idle_start_); - jiffies_passed_pid_start_ = read_proc_pid_stat(); -} - -void cpu_load_measurer::stop() { - jiffies_complete_stop_ = read_proc_stat(&jiffies_idle_stop_); - jiffies_passed_pid_stop_ = read_proc_pid_stat(); - if(jiffies_complete_stop_ < jiffies_complete_start_ || jiffies_passed_pid_stop_ < jiffies_passed_pid_start_) { - std::cerr << "Overflow of values in procfs occured, can't calculate load" << std::endl; - exit(0); - } - cpu_load_pid_ = 100.0 - * static_cast(jiffies_passed_pid_stop_ - - jiffies_passed_pid_start_) - / static_cast(jiffies_complete_stop_ - - jiffies_complete_start_); - cpu_load_overall_ = 100.0 - * static_cast((jiffies_complete_stop_ - jiffies_idle_stop_) - - (jiffies_complete_start_ - jiffies_idle_start_)) - / static_cast(jiffies_complete_stop_ - - jiffies_complete_start_); - cpu_load_pid_wo_idle_ = 100.0 - * static_cast(jiffies_passed_pid_stop_ - - jiffies_passed_pid_start_) - / static_cast((jiffies_complete_stop_ - jiffies_idle_stop_) - - (jiffies_complete_start_ - jiffies_idle_start_)); - -} - -void cpu_load_measurer::print_cpu_load() const { - std::cout << "Used Jiffies complete: " - << jiffies_complete_stop_ - jiffies_complete_start_ << " (worked: " - << (jiffies_complete_stop_ - jiffies_idle_stop_) - - (jiffies_complete_start_ - jiffies_idle_start_) - << " idled: " << jiffies_idle_stop_ - jiffies_idle_start_ - << ")" << std::endl; - std::cout << "Used Jiffies of pid " << pid_ << ": " << jiffies_passed_pid_stop_ - jiffies_passed_pid_start_ << std::endl; - std::cout << "Cpu load pid " << pid_ << " [%]: " << cpu_load_pid_ << std::endl; - std::cout << "Overall cpu load[%]: " << cpu_load_overall_ << std::endl; - std::cout << "Load caused by pid " << pid_ << " of overall cpu load [%]:" << cpu_load_pid_wo_idle_ << std::endl; -} - -double cpu_load_measurer::get_cpu_load() const { - return cpu_load_pid_; -} - -std::uint64_t cpu_load_measurer::read_proc_pid_stat() { - std::string path("/proc/" + std::to_string(pid_) + "/stat"); - FILE* f = std::fopen(path.c_str(), "r"); - if(!f) { - std::perror(std::string("Failed to open " + path).c_str()); - exit(1); - } - // see Table 1-4 Contents of the stat files (as of 2.6.30-rc7) - // at https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/filesystems/proc.txt?id=refs/tags/v3.10.98 - // and man proc (for conversion specifier) - std::uint64_t utime(0); - std::uint64_t stime(0); - std::int64_t cutime(0); - std::int64_t cstime(0); - if (std::fscanf(f, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u " - "%lu %lu %ld %ld", // utime, stime, cutime, cstime - &utime, &stime, &cutime, &cstime) == EOF) { - std::cerr << "Failed to read " + path << std::endl; - exit(1); - } - std::fclose(f); - return utime + stime + static_cast(cutime) + - static_cast(cstime); -} - -std::uint64_t cpu_load_measurer::read_proc_stat(std::uint64_t* _idle) { - FILE* f = std::fopen("/proc/stat", "r"); - if(!f) { - std::perror("Failed to open /proc/stat"); - exit(1); - } - - // see 1.8 Miscellaneous kernel statistics in /proc/stat - // at https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/filesystems/proc.txt?id=refs/tags/v3.10.98 - std::uint64_t user(0); - std::uint64_t nice(0); - std::uint64_t system(0); - std::uint64_t idle(0); - std::uint64_t iowait(0); - std::uint64_t irq(0); - std::uint64_t softirq(0); - std::uint64_t steal(0); - std::uint64_t guest(0); - std::uint64_t guest_nice(0); - if (std::fscanf(f, "%*s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", &user, - &nice, &system, &idle, &iowait, &irq, &softirq, &steal, &guest, - &guest_nice) == EOF) { - std::cerr << "Failed to read /proc/stat" << std::endl; - exit(1); - } - std::fclose(f); - *_idle = idle; - return user + nice + system + idle + iowait + irq + softirq + steal + guest - + guest_nice; -} - -bool cpu_load_measurer::read_clock_ticks() { - long val(::sysconf(_SC_CLK_TCK)); - if(val < 0 && errno == EINVAL) { - std::perror(__func__); - return false; - } - clock_ticks_ = static_cast(val); - return true; -} diff --git a/test/cpu_load_tests/cpu_load_measurer.hpp b/test/cpu_load_tests/cpu_load_measurer.hpp deleted file mode 100644 index dfdcf80..0000000 --- a/test/cpu_load_tests/cpu_load_measurer.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#pragma once - -#include - -class cpu_load_measurer { -public: - cpu_load_measurer(std::uint32_t _pid); - virtual ~cpu_load_measurer(); - void start(); - void stop(); - void print_cpu_load() const; - double get_cpu_load() const; - -private: - std::uint64_t read_proc_stat(std::uint64_t* _idle); - std::uint64_t read_proc_pid_stat(); - bool read_clock_ticks(); -private: - std::uint32_t pid_; - std::uint64_t jiffies_complete_start_; - std::uint64_t jiffies_idle_start_; - std::uint64_t jiffies_complete_stop_; - std::uint64_t jiffies_idle_stop_; - std::uint64_t clock_ticks_; - std::uint64_t jiffies_passed_pid_start_; - std::uint64_t jiffies_passed_pid_stop_; - double cpu_load_pid_; - double cpu_load_overall_; - double cpu_load_pid_wo_idle_; -}; diff --git a/test/cpu_load_tests/cpu_load_test_client.cpp b/test/cpu_load_tests/cpu_load_test_client.cpp deleted file mode 100644 index 05c8cf1..0000000 --- a/test/cpu_load_tests/cpu_load_test_client.cpp +++ /dev/null @@ -1,390 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include // for isfinite -#include - -#include "cpu_load_test_globals.hpp" -#include -#include "cpu_load_measurer.hpp" - -// for getpid -#include -#include - - -enum protocol_e { - PR_UNKNOWN, - PR_TCP, - PR_UDP -}; - -class cpu_load_test_client -{ -public: - cpu_load_test_client(protocol_e _protocol, std::uint32_t _number_of_calls, - std::uint32_t _payload_size, bool _call_service_sync, - bool _shutdown_service) : - protocol_(_protocol), - app_(vsomeip::runtime::get()->create_application("cpu_load_test_client")), - request_(vsomeip::runtime::get()->create_request(protocol_ == protocol_e::PR_TCP)), - call_service_sync_(_call_service_sync), - shutdown_service_at_end_(_shutdown_service), - sliding_window_size_(_number_of_calls), - wait_for_availability_(true), - is_available_(false), - number_of_calls_(_number_of_calls), - number_of_calls_current_(0), - number_of_sent_messages_(0), - number_of_sent_messages_total_(0), - number_of_acknowledged_messages_(0), - payload_size_(_payload_size), - wait_for_all_msg_acknowledged_(true), - initialized_(false), - sender_(std::bind(&cpu_load_test_client::run, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - initialized_ = true; - app_->register_state_handler( - std::bind(&cpu_load_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, - std::bind(&cpu_load_test_client::on_message, this, - std::placeholders::_1)); - - app_->register_availability_handler(cpu_load_test::service_id, - cpu_load_test::instance_id, - std::bind(&cpu_load_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - VSOMEIP_INFO << "Starting..."; - app_->start(); - } - - ~cpu_load_test_client() { - { - std::lock_guard its_lock(mutex_); - wait_for_availability_ = false; - condition_.notify_one(); - } - { - std::lock_guard its_lock(all_msg_acknowledged_mutex_); - wait_for_all_msg_acknowledged_ = false; - all_msg_acknowledged_cv_.notify_one(); - } - sender_.join(); - } - -private: - void stop() { - VSOMEIP_INFO << "Stopping..."; - // shutdown the service - if(shutdown_service_at_end_) - { - shutdown_service(); - } - app_->clear_all_handler(); - } - - void on_state(vsomeip::state_type_e _state) { - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - app_->request_service(cpu_load_test::service_id, - cpu_load_test::instance_id); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - VSOMEIP_INFO << "Service [" << std::setw(4) << std::setfill('0') - << std::hex << _service << "." << _instance << "] is " - << (_is_available ? "available." : "NOT available."); - - if (cpu_load_test::service_id == _service - && cpu_load_test::instance_id == _instance) { - if (is_available_ && !_is_available) { - is_available_ = false; - } else if (_is_available && !is_available_) { - is_available_ = true; - std::lock_guard its_lock(mutex_); - wait_for_availability_ = false; - condition_.notify_one(); - } - } - } - void on_message(const std::shared_ptr &_response) { - - number_of_acknowledged_messages_++; - ASSERT_EQ(_response->get_service(), cpu_load_test::service_id); - ASSERT_EQ(_response->get_method(), cpu_load_test::method_id); - if(call_service_sync_) - { - // We notify the sender thread every time a message was acknowledged - std::lock_guard lk(all_msg_acknowledged_mutex_); - wait_for_all_msg_acknowledged_ = false; - all_msg_acknowledged_cv_.notify_one(); - } - else - { - // We notify the sender thread only if all sent messages have been acknowledged - if(number_of_acknowledged_messages_ == number_of_calls_current_) - { - std::lock_guard lk(all_msg_acknowledged_mutex_); - number_of_acknowledged_messages_ = 0; - wait_for_all_msg_acknowledged_ = false; - all_msg_acknowledged_cv_.notify_one(); - } - else if(number_of_acknowledged_messages_ % sliding_window_size_ == 0) - { - std::lock_guard lk(all_msg_acknowledged_mutex_); - wait_for_all_msg_acknowledged_ = false; - all_msg_acknowledged_cv_.notify_one(); - } - } - } - - void run() { - std::unique_lock its_lock(mutex_); - while (wait_for_availability_) { - condition_.wait(its_lock); - } - - request_->set_service(cpu_load_test::service_id); - request_->set_instance(cpu_load_test::instance_id); - request_->set_method(cpu_load_test::method_id); - std::shared_ptr payload = vsomeip::runtime::get()->create_payload(); - std::vector payload_data; - payload_data.assign(payload_size_, cpu_load_test::load_test_data); - payload->set_data(payload_data); - request_->set_payload(payload); - - // lock the mutex - for(std::uint32_t i=0; i <= number_of_calls_; i++) { - number_of_calls_current_ = i; - sliding_window_size_ = i; - std::unique_lock lk(all_msg_acknowledged_mutex_); - call_service_sync_ ? send_messages_sync(lk, i) : send_messages_async(lk, i); - } - const double average_load(std::accumulate(results_.begin(), results_.end(), 0.0) / static_cast(results_.size())); - VSOMEIP_INFO << "Sent: " << number_of_sent_messages_total_ - << " messages in total (excluding control messages). This caused: " - << std::fixed << std::setprecision(2) - << average_load << "% load in average (average of " - << results_.size() << " measurements)."; - - std::vector results_no_zero; - for(const auto &v : results_) { - if(v > 0.0) { - results_no_zero.push_back(v); - } - } - const double average_load_no_zero(std::accumulate(results_no_zero.begin(), results_no_zero.end(), 0.0) / static_cast(results_no_zero.size())); - VSOMEIP_INFO << "Sent: " << number_of_sent_messages_total_ - << " messages in total (excluding control messages). This caused: " - << std::fixed << std::setprecision(2) - << average_load_no_zero << "% load in average, if measured " - << "cpu load was greater zero (average of " - << results_no_zero.size() << " measurements)."; - - wait_for_availability_ = true; - - stop(); - if (initialized_) { - app_->stop(); - } - } - - - void send_messages_sync(std::unique_lock& lk, std::uint32_t _messages_to_send) { - cpu_load_measurer c(static_cast(::getpid())); - send_service_start_measuring(true); - c.start(); - for (number_of_sent_messages_ = 0; - number_of_sent_messages_ < _messages_to_send; - number_of_sent_messages_++, number_of_sent_messages_total_++) - { - app_->send(request_); - // wait until the send messages has been acknowledged - while(wait_for_all_msg_acknowledged_) { - all_msg_acknowledged_cv_.wait(lk); - } - wait_for_all_msg_acknowledged_ = true; - } - c.stop(); - send_service_start_measuring(false); - VSOMEIP_DEBUG << "Synchronously sent " << std::setw(4) << std::setfill('0') - << number_of_sent_messages_ << " messages. CPU load [%]: " - << std::fixed << std::setprecision(2) - << (std::isfinite(c.get_cpu_load()) ? c.get_cpu_load() : 0.0); - results_.push_back(std::isfinite(c.get_cpu_load()) ? c.get_cpu_load() : 0.0); - - } - - void send_messages_async(std::unique_lock& lk, std::uint32_t _messages_to_send) { - cpu_load_measurer c(static_cast(::getpid())); - send_service_start_measuring(true); - c.start(); - for (number_of_sent_messages_ = 0; - number_of_sent_messages_ < _messages_to_send; - number_of_sent_messages_++, number_of_sent_messages_total_++) - { - app_->send(request_); - if((number_of_sent_messages_+1) % sliding_window_size_ == 0) - { - // wait until all send messages have been acknowledged - while(wait_for_all_msg_acknowledged_) { - all_msg_acknowledged_cv_.wait(lk); - } - wait_for_all_msg_acknowledged_ = true; - } - } - c.stop(); - send_service_start_measuring(false); - VSOMEIP_DEBUG << "Asynchronously sent " << std::setw(4) << std::setfill('0') - << number_of_sent_messages_ << " messages. CPU load [%]: " - << std::fixed << std::setprecision(2) - << (std::isfinite(c.get_cpu_load()) ? c.get_cpu_load() : 0.0); - results_.push_back(std::isfinite(c.get_cpu_load()) ? c.get_cpu_load() : 0.0); - } - - void send_service_start_measuring(bool _start_measuring) { - std::shared_ptr m = vsomeip::runtime::get()->create_request(protocol_ == protocol_e::PR_TCP); - m->set_service(cpu_load_test::service_id); - m->set_instance(cpu_load_test::instance_id); - _start_measuring ? m->set_method(cpu_load_test::method_id_cpu_measure_start) : m->set_method(cpu_load_test::method_id_cpu_measure_stop); - app_->send(m); - } - - void shutdown_service() { - request_->set_service(cpu_load_test::service_id); - request_->set_instance(cpu_load_test::instance_id); - request_->set_method(cpu_load_test::method_id_shutdown); - app_->send(request_); - } - -private: - protocol_e protocol_; - std::shared_ptr app_; - std::shared_ptr request_; - bool call_service_sync_; - bool shutdown_service_at_end_; - std::uint32_t sliding_window_size_; - std::mutex mutex_; - std::condition_variable condition_; - bool wait_for_availability_; - bool is_available_; - const std::uint32_t number_of_calls_; - std::uint32_t number_of_calls_current_; - std::uint32_t number_of_sent_messages_; - std::uint32_t number_of_sent_messages_total_; - std::uint32_t number_of_acknowledged_messages_; - - std::uint32_t payload_size_; - - bool wait_for_all_msg_acknowledged_; - std::mutex all_msg_acknowledged_mutex_; - std::condition_variable all_msg_acknowledged_cv_; - std::vector results_; - std::atomic initialized_; - std::thread sender_; -}; - - -// this variables are changed via cmdline parameters -static protocol_e protocol(protocol_e::PR_UNKNOWN); -static std::uint32_t number_of_calls(0); -static std::uint32_t payload_size(40); -static bool call_service_sync(true); -static bool shutdown_service(true); - - -TEST(someip_load_test, DISABLED_send_messages_and_measure_cpu_load) -{ - cpu_load_test_client test_client_(protocol, number_of_calls, payload_size, call_service_sync, shutdown_service); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - int i = 0; - while (i < argc) { - if(std::string("--protocol") == std::string(argv[i]) - || std::string("-p") == std::string(argv[i])) { - if(std::string("udp") == std::string(argv[i+1]) || - std::string("UDP") == std::string(argv[i+1])) { - protocol = protocol_e::PR_UDP; - i++; - } else if(std::string("tcp") == std::string(argv[i+1]) || - std::string("TCP") == std::string(argv[i+1])) { - protocol = protocol_e::PR_TCP; - i++; - } - } else if(std::string("--calls") == std::string(argv[i]) - || std::string("-c") == std::string(argv[i])) { - try { - number_of_calls = static_cast(std::stoul(std::string(argv[i+1]), nullptr, 10)); - } catch (const std::exception &e) { - std::cerr << "Please specify a valid value for number of calls" << std::endl; - return(EXIT_FAILURE); - } - i++; - } else if(std::string("--mode") == std::string(argv[i]) - || std::string("-m") == std::string(argv[i])) { - if(std::string("sync") == std::string(argv[i+1]) || - std::string("SYNC") == std::string(argv[i+1])) { - call_service_sync = true; - i++; - } else if(std::string("async") == std::string(argv[i+1]) || - std::string("ASYNC") == std::string(argv[i+1])) { - call_service_sync = false; - i++; - } - } else if(std::string("--payload-size") == std::string(argv[i]) - || std::string("-pl") == std::string(argv[i])) { - try { - payload_size = static_cast(std::stoul(std::string(argv[i+1]), nullptr, 10)); - } catch (const std::exception &e) { - std::cerr << "Please specify a valid values for payload size" << std::endl; - return(EXIT_FAILURE); - } - i++; - } else if(std::string("--help") == std::string(argv[i]) - || std::string("-h") == std::string(argv[i])) { - std::cout << "Available options:" << std::endl; - std::cout << "--protocol|-p: valid values TCP or UDP" << std::endl; - std::cout << "--calls|-c: number of message calls to do" << std::endl; - std::cout << "--mode|-m: mode sync or async" << std::endl; - std::cout << "--payload-size|-pl: payload size in Bytes default: 40" << std::endl; - } - i++; - } - - if(protocol == protocol_e::PR_UNKNOWN) { - std::cerr << "Please specify valid protocol mode, see --help" << std::endl; - return(EXIT_FAILURE); - } - if(!number_of_calls) { - std::cerr << "Please specify valid number of calls, see --help" << std::endl; - return(EXIT_FAILURE); - } - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/cpu_load_tests/cpu_load_test_globals.hpp b/test/cpu_load_tests/cpu_load_test_globals.hpp deleted file mode 100644 index e6897e3..0000000 --- a/test/cpu_load_tests/cpu_load_test_globals.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#pragma once - -namespace cpu_load_test { - -static constexpr vsomeip::service_t service_id(0x1111); -static constexpr vsomeip::instance_t instance_id(0x1); -static constexpr vsomeip::method_t method_id(0x1111); -static constexpr vsomeip::byte_t load_test_data(0xDD); -static constexpr vsomeip::length_t default_payload_length(40); -static constexpr vsomeip::method_t method_id_shutdown(0x7777); -static constexpr vsomeip::method_t method_id_cpu_measure_start(0x8888); -static constexpr vsomeip::method_t method_id_cpu_measure_stop(0x9999); -} diff --git a/test/cpu_load_tests/cpu_load_test_master_starter.sh b/test/cpu_load_tests/cpu_load_test_master_starter.sh deleted file mode 100755 index 138d00e..0000000 --- a/test/cpu_load_tests/cpu_load_test_master_starter.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -FAIL=0 - -export VSOMEIP_CONFIGURATION=cpu_load_test_client_master.json -./cpu_load_test_client --protocol UDP --calls 1000 & -TEST_CLIENT_PID=$! -sleep 1 - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting cpu load test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./cpu_load_test_slave_starter.sh"' & -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./cpu_load_test_slave_starter.sh" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./cpu_load_test_slave_starter.sh\" >> $WS_ROOT/slave_test_output 2>&1" & - -else -cat < - -#include - -#include -#include -#include -#include -#include -#include // for isfinite - -#include "cpu_load_test_globals.hpp" -#include -#include "cpu_load_measurer.hpp" - -// for getpid -#include -#include - -class cpu_load_test_service -{ -public: - cpu_load_test_service() : - app_(vsomeip::runtime::get()->create_application("cpu_load_test_service")), - is_registered_(false), - blocked_(false), - number_of_received_messages_(0), - number_of_received_messages_total_(0), - load_measurer_(static_cast(::getpid())), - offer_thread_(std::bind(&cpu_load_test_service::run, this)) - { - } - - ~cpu_load_test_service() { - { - std::lock_guard its_lock(mutex_); - blocked_ = true; - condition_.notify_one(); - } - offer_thread_.join(); - } - - bool init() - { - std::lock_guard its_lock(mutex_); - - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - app_->register_message_handler(cpu_load_test::service_id, - cpu_load_test::instance_id, cpu_load_test::method_id, - std::bind(&cpu_load_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_message_handler(cpu_load_test::service_id, - cpu_load_test::instance_id, cpu_load_test::method_id_shutdown, - std::bind(&cpu_load_test_service::on_message_shutdown, this, - std::placeholders::_1)); - app_->register_message_handler(cpu_load_test::service_id, - cpu_load_test::instance_id, cpu_load_test::method_id_cpu_measure_start, - std::bind(&cpu_load_test_service::on_message_start_measuring, this, - std::placeholders::_1)); - app_->register_message_handler(cpu_load_test::service_id, - cpu_load_test::instance_id, cpu_load_test::method_id_cpu_measure_stop, - std::bind(&cpu_load_test_service::on_message_stop_measuring, this, - std::placeholders::_1)); - app_->register_state_handler( - std::bind(&cpu_load_test_service::on_state, this, - std::placeholders::_1)); - return true; - } - - void start() - { - VSOMEIP_INFO << "Starting..."; - app_->start(); - } - - void stop() - { - VSOMEIP_INFO << "Stopping..."; - app_->stop_offer_service(cpu_load_test::service_id, cpu_load_test::instance_id); - app_->clear_all_handler(); - app_->stop(); - } - - void on_state(vsomeip::state_type_e _state) - { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : - "deregistered."); - - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - if(!is_registered_) - { - is_registered_ = true; - std::lock_guard its_lock(mutex_); - blocked_ = true; - // "start" the run method thread - condition_.notify_one(); - } - } - else - { - is_registered_ = false; - } - } - - void on_message(const std::shared_ptr& _request) - { - number_of_received_messages_++; - number_of_received_messages_total_++; - // send response - app_->send(vsomeip::runtime::get()->create_response(_request)); - } - - void on_message_start_measuring(const std::shared_ptr& _request) - { - (void)_request; - load_measurer_.start(); - } - - void on_message_stop_measuring(const std::shared_ptr& _request) - { - (void)_request; - load_measurer_.stop(); - VSOMEIP_DEBUG << "Received " << std::setw(4) << std::setfill('0') - << number_of_received_messages_ << " messages. CPU load [%]: " - << std::fixed << std::setprecision(2) - << (std::isfinite(load_measurer_.get_cpu_load()) ? load_measurer_.get_cpu_load() : 0.0); - results_.push_back(std::isfinite(load_measurer_.get_cpu_load()) ? load_measurer_.get_cpu_load() : 0.0); - number_of_received_messages_ = 0; - } - - void on_message_shutdown( - const std::shared_ptr& _request) - { - (void)_request; - VSOMEIP_INFO << "Shutdown method was called, going down now."; - const double average_load(std::accumulate(results_.begin(), results_.end(), 0.0) / static_cast(results_.size())); - VSOMEIP_INFO << "Received: " << number_of_received_messages_total_ - << " in total (excluding control messages). This caused: " - << std::fixed << std::setprecision(2) - << average_load << "% load in average (average of " - << results_.size() << " measurements)."; - - std::vector results_no_zero; - for(const auto &v : results_) { - if(v > 0.0) { - results_no_zero.push_back(v); - } - } - const double average_load_no_zero(std::accumulate(results_no_zero.begin(), results_no_zero.end(), 0.0) / static_cast(results_no_zero.size())); - VSOMEIP_INFO << "Sent: " << number_of_received_messages_total_ - << " messages in total (excluding control messages). This caused: " - << std::fixed << std::setprecision(2) - << average_load_no_zero << "% load in average, if measured cpu load " - << "was greater zero (average of " - << results_no_zero.size() << " measurements)."; - stop(); - } - - void run() - { - std::unique_lock its_lock(mutex_); - while (!blocked_) { - condition_.wait(its_lock); - } - - app_->offer_service(cpu_load_test::service_id, cpu_load_test::instance_id); - } - -private: - std::shared_ptr app_; - bool is_registered_; - - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - std::uint32_t number_of_received_messages_; - std::uint32_t number_of_received_messages_total_; - cpu_load_measurer load_measurer_; - std::vector results_; - std::thread offer_thread_; -}; - - -TEST(someip_payload_test, DISABLED_send_response_for_every_request) -{ - cpu_load_test_service test_service; - if (test_service.init()) { - test_service.start(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/cpu_load_tests/cpu_load_test_slave_starter.sh b/test/cpu_load_tests/cpu_load_test_slave_starter.sh deleted file mode 100755 index 83ef19d..0000000 --- a/test/cpu_load_tests/cpu_load_test_slave_starter.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -FAIL=0 - -export VSOMEIP_CONFIGURATION=cpu_load_test_service_slave.json -./cpu_load_test_service & - -# Wait until all applications are finished -for job in $(jobs -p) -do - # Fail gets incremented if one of the binaries exits - # with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -cat < - -std::vector> responses_; -std::vector> events_; - -std::map counters_; - - -e2e_profile_04_test_client::e2e_profile_04_test_client() - : app_(vsomeip::runtime::get()->create_application()), - is_available_(false), - sender_(std::bind(&e2e_profile_04_test_client::run, this)), - received_(0) { - -} - -bool -e2e_profile_04_test_client::init() { - - if (!app_->init()) { - ADD_FAILURE() << __func__ << ": Cannot initialize application"; - return (false); - } - - app_->register_state_handler( - std::bind(&e2e_profile_04_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler( - PROFILE_04_SERVICE, PROFILE_04_INSTANCE, vsomeip::ANY_METHOD, - std::bind(&e2e_profile_04_test_client::on_message, this, - std::placeholders::_1)); - - app_->register_availability_handler( - PROFILE_04_SERVICE, PROFILE_04_INSTANCE, - std::bind(&e2e_profile_04_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - - return (true); -} - -void -e2e_profile_04_test_client::start() { - - VSOMEIP_INFO << __func__ << ": Starting..."; - app_->start(); -} - -void -e2e_profile_04_test_client::stop() { - - VSOMEIP_INFO << __func__ << ": Stopping..."; - shutdown_service(); - app_->clear_all_handler(); - app_->stop(); -} - -void -e2e_profile_04_test_client::on_state(vsomeip::state_type_e _state) { - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - app_->request_service(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, false); - - // request event 0x8001, that is protected by E2E Profile 04 - app_->request_event(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, - PROFILE_04_EVENT, { PROFILE_04_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, - vsomeip::reliability_type_e::RT_UNRELIABLE); - } -} - -void -e2e_profile_04_test_client::on_availability( - vsomeip::service_t _service, vsomeip::instance_t _instance, - bool _is_available) { - - VSOMEIP_INFO << __func__ << ": Client " - << std::hex << std::setw(4) << std::setfill('0') - << app_->get_client() - << " : Service [" << _service << "." << _instance - << "] is " << (_is_available ? "available." : "NOT available."); - - // check that correct service / instance ID gets available - if (_is_available) { - EXPECT_EQ(PROFILE_04_SERVICE, _service); - EXPECT_EQ(PROFILE_04_INSTANCE, _instance); - } - - if (PROFILE_04_SERVICE == _service && PROFILE_04_INSTANCE == _instance) { - std::unique_lock its_lock(mutex_); - if (is_available_ && !_is_available) { - is_available_ = false; - } else if(_is_available && !is_available_) { - is_available_ = true; - - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - app_->subscribe(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, - PROFILE_04_EVENTGROUP, PROFILE_04_MAJOR); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - condition_.notify_one(); - } - } -} - -void -e2e_profile_04_test_client::on_message(const std::shared_ptr &_message) { - - VSOMEIP_INFO << __func__ << ": Received a message from Service [" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_service() << "." << _message->get_instance() - << "] to Client/Session [" - << _message->get_client() << "/" << _message->get_session() - << "]"; - - EXPECT_EQ(PROFILE_04_SERVICE, _message->get_service()); - EXPECT_EQ(PROFILE_04_INSTANCE, _message->get_instance()); - - // check fixed payload / CRC in response for service: d025 method: 0001 - if (vsomeip::message_type_e::MT_RESPONSE == _message->get_message_type() - && PROFILE_04_METHOD == _message->get_method()) { - // check for calculated CRC status OK for the predefined fixed payload sent by service - VSOMEIP_INFO << "Method ID 0x0001 -> IS_VALID_CRC = " - << std::boolalpha << _message->is_valid_crc(); - EXPECT_EQ(true, _message->is_valid_crc()); - - // check if payload is as expected as well (including CRC / counter / data ID) - std::shared_ptr its_payload = _message->get_payload(); - const auto its_data = its_payload->get_data(); - for (size_t i = 0; i < its_payload->get_length(); i++) - EXPECT_EQ(its_data[i], responses_[counters_[PROFILE_04_METHOD] - % PROFILE_O4_NUM_MESSAGES][i]); - - counters_[PROFILE_04_METHOD]++; - - } else if (vsomeip::message_type_e::MT_NOTIFICATION == _message->get_message_type() - && PROFILE_04_EVENT == _message->get_method()) { - - // check CRC / payload calculated by sender for event 0x8001 against expected payload - // check for calculated CRC status OK for the calculated CRC / payload sent by service - VSOMEIP_INFO << __func__ << ": Event 0x8001 -> IS_VALID_CRC = " - << std::boolalpha << _message->is_valid_crc(); - EXPECT_EQ(true, _message->is_valid_crc()); - - // check if payload is as expected as well (including CRC / counter / data ID nibble) - std::shared_ptr its_payload = _message->get_payload(); - const auto its_data = its_payload->get_data(); - for (size_t i = 0; i< its_payload->get_length(); i++) - EXPECT_EQ(its_data[i], events_[counters_[PROFILE_04_EVENT] - % PROFILE_O4_NUM_MESSAGES][i]); - - counters_[PROFILE_04_EVENT]++; - } - - received_++; - if (received_ == PROFILE_O4_NUM_MESSAGES * 2) { - VSOMEIP_WARNING << __func__ << ": Client" - << std::setw(4) << std::setfill('0') << std::hex - << app_->get_client() - << " received all messages ~> going down!"; - } -} - -void -e2e_profile_04_test_client::run() { - - for (int i = 0; i < PROFILE_O4_NUM_MESSAGES; ++i) { - { - std::unique_lock its_lock(mutex_); - while (!is_available_) { - condition_.wait(its_lock); - } - } - - auto request = vsomeip::runtime::get()->create_request(false); - request->set_service(PROFILE_04_SERVICE); - request->set_instance(PROFILE_04_INSTANCE); - request->set_interface_version(PROFILE_04_MAJOR); - - // send a request which is not e2e protected and expect an - // protected answer holding a fixed payload (E2E Profile 04) - // this call triggers also an event 0x8001 which holds a - // calculated payload - request->set_method(PROFILE_04_METHOD); - - app_->send(request); - - std::this_thread::sleep_for(std::chrono::milliseconds(250)); - } - - stop(); -} - -void -e2e_profile_04_test_client::join_sender_thread() { - - if (sender_.joinable()) { - sender_.join(); - } -} - -void -e2e_profile_04_test_client::shutdown_service() { - - auto request = vsomeip::runtime::get()->create_request(false); - request->set_service(PROFILE_04_SERVICE); - request->set_instance(PROFILE_04_INSTANCE); - request->set_method(PROFILE_04_SHUTDOWN); - request->set_interface_version(PROFILE_04_MAJOR); - - app_->send(request); - - std::this_thread::sleep_for(std::chrono::milliseconds(250)); - - // expect 10 responses + 10 events - EXPECT_EQ(received_, PROFILE_O4_NUM_MESSAGES * 2); -} - -TEST(someip_e2e_profile_04_test, test_crc_calculation) { - - e2e_profile_04_test_client test_client; - - if (test_client.init()) { - test_client.start(); - test_client.join_sender_thread(); - } -} - -int main(int argc, char** argv) { - - responses_ = { - { - 0x00, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00, 0x2d, - 0xaa, 0x1d, 0x3f, 0xdf, 0x08, 0xb7, 0xf4, 0x4c, - 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, - 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, - 0x3d, 0x83, 0x3e, 0xba, 0x68, 0xed, 0x3f, 0xb3, - 0x7a, 0xf2, 0xbd, 0x96, 0xc1, 0x42, 0x3d, 0x25, - 0x1a, 0x62, 0xbd, 0xae, 0x77, 0xf3, 0x3f, 0x80, - 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1d, 0xbd, - 0x4e, 0x01, 0x01, 0x3c, 0x2b, 0x87, 0xed, 0x00 - }, - { - 0x00, 0x50, 0x00, 0x01, 0x01, 0x00, 0x00, 0x2d, - 0xe7, 0xb7, 0x13, 0x87, 0x0c, 0x69, 0x02, 0x1c, - 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, - 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, - 0x3c, 0x2f, 0x3e, 0xba, 0x46, 0x81, 0x3f, 0xb3, - 0x73, 0x8d, 0xbd, 0x93, 0xcb, 0xae, 0x3c, 0xf7, - 0xd2, 0x58, 0xbd, 0xa2, 0x6e, 0xcd, 0x3f, 0x80, - 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x89, - 0x24, 0x01, 0x01, 0x3c, 0x2b, 0x24, 0x45, 0x00 - }, - { - 0x00, 0x50, 0x00, 0x02, 0x01, 0x00, 0x00, 0x2d, - 0xb6, 0x19, 0x94, 0x2c, 0x10, 0x1b, 0x28, 0xae, - 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, - 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, - 0x3e, 0xf3, 0x3e, 0xba, 0x97, 0x45, 0x3f, 0xb3, - 0x86, 0x81, 0xbd, 0x8a, 0xda, 0xc2, 0x3c, 0xf6, - 0x00, 0x7a, 0xbd, 0xb4, 0xf9, 0xb9, 0x3f, 0x80, - 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x1b, - 0x72, 0x01, 0x01, 0x3c, 0x2a, 0x9e, 0x1f, 0x00 - } - }; - - events_ = { - { - 0x00, 0x50, 0x8f, 0x81, 0x01, 0x00, 0x00, 0x2d, - 0xed, 0x6e, 0x78, 0x8d, 0x08, 0xb7, 0xf4, 0x4c, - 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, - 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, - 0x3d, 0x83, 0x3e, 0xba, 0x68, 0xed, 0x3f, 0xb3, - 0x7a, 0xf2, 0xbd, 0x96, 0xc1, 0x42, 0x3d, 0x25, - 0x1a, 0x62, 0xbd, 0xae, 0x77, 0xf3, 0x3f, 0x80, - 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1d, 0xbd, - 0x4e, 0x01, 0x01, 0x3c, 0x2b, 0x87, 0xed, 0x00 - }, - { - 0x00, 0x50, 0x8f, 0x82, 0x01, 0x00, 0x00, 0x2d, - 0x9d, 0xbb, 0x49, 0x3f, 0x0c, 0x69, 0x02, 0x1c, - 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, - 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, - 0x3c, 0x2f, 0x3e, 0xba, 0x46, 0x81, 0x3f, 0xb3, - 0x73, 0x8d, 0xbd, 0x93, 0xcb, 0xae, 0x3c, 0xf7, - 0xd2, 0x58, 0xbd, 0xa2, 0x6e, 0xcd, 0x3f, 0x80, - 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x89, - 0x24, 0x01, 0x01, 0x3c, 0x2b, 0x24, 0x45, 0x00 - }, - { - 0x00, 0x50, 0x8f, 0x83, 0x01, 0x00, 0x00, 0x2d, - 0x13, 0x04, 0xf8, 0x81, 0x10, 0x1b, 0x28, 0xae, - 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, - 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, - 0x3e, 0xf3, 0x3e, 0xba, 0x97, 0x45, 0x3f, 0xb3, - 0x86, 0x81, 0xbd, 0x8a, 0xda, 0xc2, 0x3c, 0xf6, - 0x00, 0x7a, 0xbd, 0xb4, 0xf9, 0xb9, 0x3f, 0x80, - 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x1b, - 0x72, 0x01, 0x01, 0x3c, 0x2a, 0x9e, 0x1f, 0x00 - } - }; - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/e2e_tests/e2e_profile_04_test_client.hpp b/test/e2e_tests/e2e_profile_04_test_client.hpp deleted file mode 100644 index ad00291..0000000 --- a/test/e2e_tests/e2e_profile_04_test_client.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef E2E_PROFILE_04_TEST_CLIENT_HPP_ -#define E2E_PROFILE_04_TEST_CLIENT_HPP_ - -#include - -#include - -#include -#include -#include -#include - -class e2e_profile_04_test_client { -public: - e2e_profile_04_test_client(); - - bool init(); - void start(); - void stop(); - - void on_state(vsomeip::state_type_e _state); - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available); - void on_message(const std::shared_ptr &_response); - - void run(); - void join_sender_thread(); - -private: - void shutdown_service(); - - std::shared_ptr app_; - - std::mutex mutex_; - std::condition_variable condition_; - bool is_available_; - - std::thread sender_; - - std::atomic received_; -}; - -#endif // E2E_PROFILE_04_TEST_CLIENT_HPP_ diff --git a/test/e2e_tests/e2e_profile_04_test_common.hpp b/test/e2e_tests/e2e_profile_04_test_common.hpp deleted file mode 100644 index 04cba23..0000000 --- a/test/e2e_tests/e2e_profile_04_test_common.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef E2E_PROFILE_04_TEST_COMMON_HPP_ -#define E2E_PROFILE_04_TEST_COMMON_HPP_ - -#include - -const vsomeip::service_t PROFILE_04_SERVICE = 0xd025; -const vsomeip::instance_t PROFILE_04_INSTANCE = 0x0001; -const vsomeip::major_version_t PROFILE_04_MAJOR = 0x01; -const vsomeip::minor_version_t PROFILE_04_MINOR = 0x00000000; - -const vsomeip::method_t PROFILE_04_METHOD = 0x0001; -const vsomeip::method_t PROFILE_04_SHUTDOWN = 0x0002; - -const vsomeip::eventgroup_t PROFILE_04_EVENTGROUP = 0x0001; -const vsomeip::event_t PROFILE_04_EVENT = 0x8001; - -#define PROFILE_O4_NUM_MESSAGES 3 - -#endif // E2E_PROFILE_04_TEST_COMMON_HPP_ diff --git a/test/e2e_tests/e2e_profile_04_test_external_master_start.sh b/test/e2e_tests/e2e_profile_04_test_external_master_start.sh deleted file mode 100755 index f3d6e34..0000000 --- a/test/e2e_tests/e2e_profile_04_test_external_master_start.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 1 ] -then - echo "Please pass a json file to this script" - echo "For example: $0 e2e_profile_04_test_client_external.json" - exit 1 -fi - -MASTER_JSON_FILE=$1 -SERVICE_JSON_FILE=${MASTER_JSON_FILE/client/service} -ALLOW_DENY=$2 - -FAIL=0 - -export VSOMEIP_CONFIGURATION=$1 -export VSOMEIP_APPLICATION_NAME=client-sample -./e2e_profile_04_test_client --remote & -PID_CLIENT=$! - - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting external e2e profile 04 test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./e2e_profile_04_test_external_slave_start.sh $SERVICE_JSON_FILE\"" & -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./e2e_profile_04_test_external_slave_start.sh $SERVICE_JSON_FILE" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./e2e_profile_04_test_external_slave_start.sh $SERVICE_JSON_FILE\" >> $WS_ROOT/slave_test_output 2>&1" & - -else -cat < > responses_; -std::vector > events_; - -std::map counters_; - -e2e_profile_04_test_service::e2e_profile_04_test_service() - : app_(vsomeip::runtime::get()->create_application()), - is_registered_(false), - blocked_(false), - offer_thread_(std::bind(&e2e_profile_04_test_service::run, this)), - received_(0) { -} - -bool -e2e_profile_04_test_service::init() { - - std::lock_guard its_lock(mutex_); - - if (!app_->init()) { - ADD_FAILURE() << __func__ << ": Cannot initialize application."; - return false; - } - - app_->register_message_handler(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, - PROFILE_04_METHOD, - std::bind(&e2e_profile_04_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_message_handler(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, - PROFILE_04_SHUTDOWN, - std::bind(&e2e_profile_04_test_service::on_message_shutdown, this, - std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&e2e_profile_04_test_service::on_state, this, - std::placeholders::_1)); - - // E2E Profile 04: Event 8001 - app_->offer_event(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, - PROFILE_04_EVENT, { PROFILE_04_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); - - // Initialize the attribute - auto its_payload = vsomeip::runtime::get()->create_payload(); - vsomeip::byte_t its_data[] = { - 0x00, 0x50, 0x8f, 0x80, 0x01, 0x00, 0x00, 0x2d, - 0xf3, 0x2a, 0x8c, 0x89, 0x05, 0x04, 0xcc, 0x46, - 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, - 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, - 0x40, 0xb1, 0x3e, 0xba, 0xc4, 0x76, 0x3f, 0xb3, - 0x7b, 0x03, 0xbd, 0x95, 0x74, 0x53, 0x3d, 0x32, - 0x4b, 0x9d, 0xbd, 0xbc, 0xd6, 0x3b, 0x3f, 0x80, - 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1f, 0xf5, - 0xf6, 0x01, 0x01, 0x3c, 0x2b, 0xb1, 0xa2, 0x00 - }; - its_payload->set_data(its_data, sizeof(its_data)); - - app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8001), its_payload); - - return (true); -} - -void -e2e_profile_04_test_service::start() { - - VSOMEIP_INFO << __func__ << ": Starting..."; - app_->start(); -} - -void -e2e_profile_04_test_service::stop() { - - VSOMEIP_INFO << __func__ << ": Stopping..."; - app_->clear_all_handler(); - app_->stop(); -} - -void -e2e_profile_04_test_service::join_offer_thread() { - - if (offer_thread_.joinable()) { - offer_thread_.join(); - } -} - -void -e2e_profile_04_test_service::offer() { - - app_->offer_service(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, - PROFILE_04_MAJOR, PROFILE_04_MINOR); -} - -void -e2e_profile_04_test_service::stop_offer() { - - app_->stop_offer_service(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, - PROFILE_04_MAJOR, PROFILE_04_MINOR); -} - -void -e2e_profile_04_test_service::on_state(vsomeip::state_type_e _state) { - - VSOMEIP_INFO << __func__ << ": Application " - << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - if (!is_registered_) { - is_registered_ = true; - - std::lock_guard its_lock(mutex_); - blocked_ = true; - - // "start" the run method thread - condition_.notify_one(); - } - } else { - is_registered_ = false; - } -} - -void -e2e_profile_04_test_service::on_message( - const std::shared_ptr &_request) { - - ASSERT_EQ(PROFILE_04_SERVICE, _request->get_service()); - ASSERT_EQ(PROFILE_04_INSTANCE, _request->get_instance()); - - VSOMEIP_INFO << "Received a message with Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex - << _request->get_client() << "/" << _request->get_session() - << "] method: " << _request->get_method() ; - - std::shared_ptr its_response = - vsomeip::runtime::get()->create_response(_request); - std::shared_ptr< vsomeip::payload > its_response_payload = - vsomeip::runtime::get()->create_payload(); - std::shared_ptr its_event_payload = - vsomeip::runtime::get()->create_payload(); - - // send fixed payload for profile 01 CRC8 - if (PROFILE_04_METHOD == _request->get_method()) { - its_response_payload->set_data(responses_[counters_[PROFILE_04_METHOD] % PROFILE_O4_NUM_MESSAGES]); - its_response->set_payload(its_response_payload); - app_->send(its_response); - - counters_[PROFILE_04_METHOD]++; - - // set value to field which gets filled by e2e protection with CRC on sending - its_event_payload->set_data(events_[counters_[PROFILE_04_EVENT] % PROFILE_O4_NUM_MESSAGES]); - app_->notify(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, PROFILE_04_EVENT, its_event_payload); - - counters_[PROFILE_04_EVENT]++; - } - - received_++; - if (received_ == PROFILE_O4_NUM_MESSAGES) { - VSOMEIP_INFO << __func__ << ": Received all messages!"; - } -} - -void -e2e_profile_04_test_service::on_message_shutdown( - const std::shared_ptr &_request) { - - (void)_request; - VSOMEIP_INFO << __func__ << ": Shutdown method was called, going down now."; - stop(); -} - -void -e2e_profile_04_test_service::run() { - - std::unique_lock its_lock(mutex_); - while (!blocked_) - condition_.wait(its_lock); - - offer(); -} - -TEST(someip_e2e_profile_04_test, basic_subscribe_request_response) { - e2e_profile_04_test_service test_service; - if (test_service.init()) { - test_service.start(); - test_service.join_offer_thread(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) { - - - counters_[PROFILE_04_METHOD] = 0; - counters_[PROFILE_04_EVENT] = 0; - - std::string test_remote("--remote"); - std::string test_local("--local"); - std::string test_allow_remote_client("--allow"); - std::string test_deny_remote_client("--deny"); - std::string help("--help"); - - int i = 1; - while (i < argc) - { - if(test_remote == argv[i]) - { - is_remote_test = true; - } - else if(test_local == argv[i]) - { - is_remote_test = false; - } - else if(test_allow_remote_client == argv[i]) - { - remote_client_allowed = true; - } - else if(test_deny_remote_client == argv[i]) - { - remote_client_allowed = false; - } - else if(help == argv[i]) - { - VSOMEIP_INFO << "Parameters:\n" - << "--remote: Run test between two hosts\n" - << "--local: Run test locally\n" - << "--allow: test is started with a policy that allows remote messages sent by this test client to the service\n" - << "--deny: test is started with a policy that denies remote messages sent by this test client to the service\n" - << "--help: print this help"; - } - i++; - } - - // Payloads (without counter, data id and crc) - responses_ = { - { - 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0xb7, 0xf4, 0x4c, - 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, - 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, - 0x3d, 0x83, 0x3e, 0xba, 0x68, 0xed, 0x3f, 0xb3, - 0x7a, 0xf2, 0xbd, 0x96, 0xc1, 0x42, 0x3d, 0x25, - 0x1a, 0x62, 0xbd, 0xae, 0x77, 0xf3, 0x3f, 0x80, - 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1d, 0xbd, - 0x4e, 0x01, 0x01, 0x3c, 0x2b, 0x87, 0xed, 0x00 - }, - { - 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0c, 0x69, 0x02, 0x1c, - 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, - 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, - 0x3c, 0x2f, 0x3e, 0xba, 0x46, 0x81, 0x3f, 0xb3, - 0x73, 0x8d, 0xbd, 0x93, 0xcb, 0xae, 0x3c, 0xf7, - 0xd2, 0x58, 0xbd, 0xa2, 0x6e, 0xcd, 0x3f, 0x80, - 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x89, - 0x24, 0x01, 0x01, 0x3c, 0x2b, 0x24, 0x45, 0x00 - }, - { - 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x1b, 0x28, 0xae, - 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, - 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, - 0x3e, 0xf3, 0x3e, 0xba, 0x97, 0x45, 0x3f, 0xb3, - 0x86, 0x81, 0xbd, 0x8a, 0xda, 0xc2, 0x3c, 0xf6, - 0x00, 0x7a, 0xbd, 0xb4, 0xf9, 0xb9, 0x3f, 0x80, - 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x1b, - 0x72, 0x01, 0x01, 0x3c, 0x2a, 0x9e, 0x1f, 0x00 - } - }; - - // Payloads (full data with counter, data id and crc to be sent raw) - events_ = { - { - 0x00, 0x50, 0x8f, 0x81, 0x01, 0x00, 0x00, 0x2d, - 0xed, 0x6e, 0x78, 0x8d, 0x08, 0xb7, 0xf4, 0x4c, - 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, - 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, - 0x3d, 0x83, 0x3e, 0xba, 0x68, 0xed, 0x3f, 0xb3, - 0x7a, 0xf2, 0xbd, 0x96, 0xc1, 0x42, 0x3d, 0x25, - 0x1a, 0x62, 0xbd, 0xae, 0x77, 0xf3, 0x3f, 0x80, - 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1d, 0xbd, - 0x4e, 0x01, 0x01, 0x3c, 0x2b, 0x87, 0xed, 0x00 - }, - { - 0x00, 0x50, 0x8f, 0x82, 0x01, 0x00, 0x00, 0x2d, - 0x9d, 0xbb, 0x49, 0x3f, 0x0c, 0x69, 0x02, 0x1c, - 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, - 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, - 0x3c, 0x2f, 0x3e, 0xba, 0x46, 0x81, 0x3f, 0xb3, - 0x73, 0x8d, 0xbd, 0x93, 0xcb, 0xae, 0x3c, 0xf7, - 0xd2, 0x58, 0xbd, 0xa2, 0x6e, 0xcd, 0x3f, 0x80, - 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x89, - 0x24, 0x01, 0x01, 0x3c, 0x2b, 0x24, 0x45, 0x00 - }, - { - 0x00, 0x50, 0x8f, 0x83, 0x01, 0x00, 0x00, 0x2d, - 0x13, 0x04, 0xf8, 0x81, 0x10, 0x1b, 0x28, 0xae, - 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, - 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, - 0x3e, 0xf3, 0x3e, 0xba, 0x97, 0x45, 0x3f, 0xb3, - 0x86, 0x81, 0xbd, 0x8a, 0xda, 0xc2, 0x3c, 0xf6, - 0x00, 0x7a, 0xbd, 0xb4, 0xf9, 0xb9, 0x3f, 0x80, - 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x1b, - 0x72, 0x01, 0x01, 0x3c, 0x2a, 0x9e, 0x1f, 0x00 - } - }; - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/e2e_tests/e2e_profile_04_test_service.hpp b/test/e2e_tests/e2e_profile_04_test_service.hpp deleted file mode 100644 index 626db05..0000000 --- a/test/e2e_tests/e2e_profile_04_test_service.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef E2E_PROFILE_04_TEST_SERVICE_HPP_ -#define E2E_PROFILE_04_TEST_SERVICE_HPP_ - -#include - -#include - -#include "../someip_test_globals.hpp" - -#include -#include -#include -#include - -class e2e_profile_04_test_service { -public: - e2e_profile_04_test_service(); - - bool init(); - void start(); - void stop(); - void offer(); - void stop_offer(); - void join_offer_thread(); - void on_state(vsomeip::state_type_e _state); - void on_message(const std::shared_ptr &_request); - void on_message_shutdown(const std::shared_ptr &_request); - void run(); - -private: - std::shared_ptr app_; - bool is_registered_; - - bool blocked_; - std::mutex mutex_; - std::condition_variable condition_; - - std::thread offer_thread_; - - std::atomic received_; -}; - -#endif // E2E_PROFILE_04_TEST_SERVICE_HPP_ diff --git a/test/e2e_tests/e2e_test_client.cpp b/test/e2e_tests/e2e_test_client.cpp deleted file mode 100644 index 260ad7e..0000000 --- a/test/e2e_tests/e2e_test_client.cpp +++ /dev/null @@ -1,387 +0,0 @@ -// Copyright (C) 2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "e2e_test_client.hpp" - -static bool is_remote_test = false; -static bool remote_client_allowed = true; -std::vector> payloads_profile_01_; -std::vector> event_payloads_profile_01_; - -std::vector> payloads_custom_profile_; -std::vector> event_payloads_custom_profile_; - -std::map received_responses_counters_; - - -e2e_test_client::e2e_test_client(bool _test_external_communication, - bool _is_remote_client_allowed) - : app_(vsomeip::runtime::get()->create_application()), - is_available_(false), - sender_(std::bind(&e2e_test_client::run, this)), - received_responses_(0), - received_allowed_events_(0), - test_external_communication_(_test_external_communication), - is_remote_client_allowed_(_is_remote_client_allowed) { - -} - -bool e2e_test_client::init() { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - - app_->register_state_handler( - std::bind(&e2e_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, - std::bind(&e2e_test_client::on_message, this, - std::placeholders::_1)); - - app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - std::bind(&e2e_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - return true; -} - -void e2e_test_client::start() { - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void e2e_test_client::stop() { - VSOMEIP_INFO << "Stopping..."; - shutdown_service(); - app_->clear_all_handler(); - app_->stop(); -} - -void e2e_test_client::on_state(vsomeip::state_type_e _state) { - if(_state == vsomeip::state_type_e::ST_REGISTERED) { - app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); - - // request events of eventgroup 0x01 which holds events 0x8001 (CRC8) - std::set its_eventgroups; - its_eventgroups.insert(0x01); - - // request events of eventgroup 0x02 which holds events 0x8002 (CRC32) - std::set its_eventgroups_2; - its_eventgroups_2.insert(0x02); - - app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8001), - its_eventgroups, vsomeip::event_type_e::ET_FIELD, - vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8002), - its_eventgroups_2, vsomeip::event_type_e::ET_FIELD, - vsomeip::reliability_type_e::RT_UNRELIABLE); - } -} - -void e2e_test_client::on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - - VSOMEIP_INFO << std::hex << "Client 0x" << app_->get_client() - << " : Service [" << std::setw(4) << std::setfill('0') << std::hex - << _service << "." << _instance << "] is " - << (_is_available ? "available." : "NOT available."); - - // check that correct service / instance ID gets available - if (_is_available) { - EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _service); - EXPECT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _instance); - } - - if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service - && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) { - std::unique_lock its_lock(mutex_); - if(is_available_ && !_is_available) { - is_available_ = false; - } - else if(_is_available && !is_available_) { - is_available_ = true; - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - app_->subscribe(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, 0x01); - app_->subscribe(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, 0x02); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - condition_.notify_one(); - } - } -} - -void e2e_test_client::on_message(const std::shared_ptr &_response) { - VSOMEIP_INFO << "Received a response from Service [" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() - << "." - << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() - << "] to Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() - << "/" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() - << "]"; - EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _response->get_service()); - EXPECT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _response->get_instance()); - - // check fixed payload / CRC in response for service: 1234 method: 8421 - if (_response->get_message_type() == vsomeip::message_type_e::MT_RESPONSE - && vsomeip_test::TEST_SERVICE_METHOD_ID == _response->get_method()) { - // check for calculated CRC status OK for the predefined fixed payload sent by service - VSOMEIP_INFO << "Method ID 0x8421 -> IS_VALID_CRC 8 = " << std::hex << _response->is_valid_crc(); - EXPECT_EQ(true, _response->is_valid_crc()); - - // check if payload is as expected as well (including CRC / counter / data ID nibble) - std::shared_ptr pl = _response->get_payload(); - uint8_t* dataptr = pl->get_data(); //start after length field - for(uint32_t i = 0; i< pl->get_length(); i++) { - EXPECT_EQ(dataptr[i], payloads_profile_01_[received_responses_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND][i]); - } - received_responses_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID]++; - } else if (_response->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION - && 0x8001 == _response->get_method()) { - // check CRC / payload calculated by sender for event 0x8001 against expected payload - // check for calculated CRC status OK for the calculated CRC / payload sent by service - VSOMEIP_INFO << "Event ID 0x8001 -> IS_VALID_CRC 8 = " << std::hex << _response->is_valid_crc(); - EXPECT_EQ(true, _response->is_valid_crc()); - - // check if payload is as expected as well (including CRC / counter / data ID nibble) - std::shared_ptr pl = _response->get_payload(); - uint8_t* dataptr = pl->get_data(); //start after length field - for(uint32_t i = 0; i< pl->get_length(); i++) { - EXPECT_EQ(dataptr[i], event_payloads_profile_01_[received_responses_counters_[0x8001] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND][i]); - } - received_responses_counters_[0x8001]++; - } else if (_response->get_message_type() == vsomeip::message_type_e::MT_RESPONSE - && 0x6543 == _response->get_method()) { - // check for calculated CRC status OK for the predefined fixed payload sent by service - VSOMEIP_INFO << "Method ID 0x6543 -> IS_VALID_CRC 32 = " << std::hex << _response->is_valid_crc(); - EXPECT_EQ(true, _response->is_valid_crc()); - - // check if payload is as expected as well (including CRC / counter / data ID nibble) - std::shared_ptr pl = _response->get_payload(); - uint8_t* dataptr = pl->get_data(); //start after length field - for(uint32_t i = 0; i< pl->get_length(); i++) { - EXPECT_EQ(dataptr[i], payloads_custom_profile_[received_responses_counters_[0x6543] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND][i]); - } - received_responses_counters_[0x6543]++; - } else if (_response->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION - && 0x8002 == _response->get_method()) { - VSOMEIP_INFO << "Event ID 0x8002 -> IS_VALID_CRC 32 = " << std::hex << _response->is_valid_crc(); - EXPECT_EQ(true, _response->is_valid_crc()); - - // check if payload is as expected as well (including CRC) - std::shared_ptr pl = _response->get_payload(); - uint8_t* dataptr = pl->get_data(); //start after length field - for(uint32_t i = 0; i< pl->get_length(); i++) { - EXPECT_EQ(dataptr[i], event_payloads_custom_profile_[received_responses_counters_[0x8002] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND][i]); - } - received_responses_counters_[0x8002]++; - } - - received_responses_++; - if (received_responses_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND * 4) { - VSOMEIP_WARNING << std::hex << app_->get_client() - << ": Received all messages ~> going down!"; - } -} - -void e2e_test_client::run() { - for (uint32_t i = 0; i < vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND; ++i) { - { - std::unique_lock its_lock(mutex_); - while (!is_available_) - { - condition_.wait(its_lock); - } - } - auto request = vsomeip::runtime::get()->create_request(false); - request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - - // send a request which is not e2e protected and expect an - // protected answer holding a fixed payload (profile 01 CRC8) - // this call triggers also an event 0x8001 which holds a calculated payload - request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); - app_->send(request); - - // send a request which is not e2e protected and expect an - // protected answer holding a fixed payload (custom profile CRC32) - // this call triggers also an event 0x8002 which holds a calculated payload - request->set_method(0x6543); - app_->send(request); - - std::this_thread::sleep_for(std::chrono::milliseconds(250)); - } - stop(); -} - -void e2e_test_client::join_sender_thread() -{ - if (sender_.joinable()) { - sender_.join(); - } -} - -void e2e_test_client::shutdown_service() { - auto request = vsomeip::runtime::get()->create_request(false); - request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); - app_->send(request); - std::this_thread::sleep_for(std::chrono::milliseconds(250)); - - // expect 10 x response messages for both method IDs and events for both Event IDs - EXPECT_EQ(received_responses_, vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND * 4); - //EXPECT_EQ(received_allowed_events_, vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND); -} - -TEST(someip_e2e_test, basic_subscribe_request_response) -{ - e2e_test_client test_client(is_remote_test, remote_client_allowed); - if (test_client.init()) { - test_client.start(); - test_client.join_sender_thread(); - } -} - -int main(int argc, char** argv) { - - /* - e2e profile01 CRC8 protected fixed sample payloads sent by service - which must be received in client using the following config on client side: - "service_id" : "0x1234", - "event_id" : "0x8421", - "profile" : "CRC8", - "variant" : "checker", - "crc_offset" : "0", - "data_id_mode" : "3", - "data_length" : "56", - "data_id" : "0xA73" - */ - payloads_profile_01_.push_back({{0x82, 0xa4, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); // initial event - payloads_profile_01_.push_back({{0x39, 0xa8, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x87, 0xa4, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x3c, 0xa8, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x55, 0xac, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x82, 0xa4, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x39, 0xa8, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x87, 0xa4, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x3c, 0xa8, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x55, 0xac, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); - - /* - e2e profile01 CRC8 protected payloads which shall be created by e2e module on - service side using the following config on client side: - "service_id" : "0x1234", - "event_id" : "0x8001", - "profile" : "CRC8", - "variant" : "checker", - "crc_offset" : "0", - "data_id_mode" : "3", - "data_length" : "56", - "data_id" : "0xA73" - */ - event_payloads_profile_01_.push_back({{0xa4, 0xa1, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff}}); // initial event - event_payloads_profile_01_.push_back({{0x05, 0xa2, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff}}); - event_payloads_profile_01_.push_back({{0x92, 0xa3, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff}}); - event_payloads_profile_01_.push_back({{0x5a, 0xa4, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff}}); - event_payloads_profile_01_.push_back({{0xc8, 0xa5, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff}}); - event_payloads_profile_01_.push_back({{0x69, 0xa6, 0x05, 0xff, 0xff, 0xff, 0xff, 0xff}}); - event_payloads_profile_01_.push_back({{0xfe, 0xa7, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff}}); - event_payloads_profile_01_.push_back({{0xe4, 0xa8, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff}}); - event_payloads_profile_01_.push_back({{0x7c, 0xa9, 0x08, 0xff, 0xff, 0xff, 0xff, 0xff}}); - event_payloads_profile_01_.push_back({{0xdd, 0xaa, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff}}); - - /* - e2e custom profile CRR32 protected fixed sample payloads sent by service - which must be received in client using the following config on client side: - "service_id" : "0x1234", - "event_id" : "0x6543", - "profile" : "CRC32", - "variant" : "checker", - "crc_offset" : "0" - */ - payloads_custom_profile_.push_back({{0xa4, 0xb2, 0x75, 0x1f, 0xff, 0x00, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa5, 0x70, 0x1f, 0x28, 0xff, 0x01, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa7, 0x36, 0xa1, 0x71, 0xff, 0x02, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa6, 0xf4, 0xcb, 0x46, 0xff, 0x03, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa3, 0xbb, 0xdd, 0xc3, 0xff, 0x04, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa2, 0x79, 0xb7, 0xf4, 0xff, 0x05, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa0, 0x3f, 0x09, 0xad, 0xff, 0x06, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa1, 0xfd, 0x63, 0x9a, 0xff, 0x07, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xaa, 0xa1, 0x24, 0xa7, 0xff, 0x08, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xab, 0x63, 0x4e, 0x90, 0xff, 0x09, 0xff, 0x32}}); - - /* - e2e custom profile CRC32 protected payloads which shall be created by e2e module on - service side using the following config on client side for checking: - "service_id" : "0x1234", - "event_id" : "0x8002", - "profile" : "CRC32", - "variant" : "checker", - "crc_offset" : "0" - */ - event_payloads_custom_profile_.push_back({{0x89, 0x0e, 0xbc, 0x80, 0xff, 0xff, 0x00, 0x32}}); - event_payloads_custom_profile_.push_back({{0x90, 0x15, 0x8d, 0xc1, 0xff, 0xff, 0x01, 0x32}}); - event_payloads_custom_profile_.push_back({{0xbb, 0x38, 0xde, 0x02, 0xff, 0xff, 0x02, 0x32}}); - event_payloads_custom_profile_.push_back({{0xa2, 0x23, 0xef, 0x43, 0xff, 0xff, 0x03, 0x32}}); - event_payloads_custom_profile_.push_back({{0xed, 0x62, 0x79, 0x84, 0xff, 0xff, 0x04, 0x32}}); - event_payloads_custom_profile_.push_back({{0xf4, 0x79, 0x48, 0xc5, 0xff, 0xff, 0x05, 0x32}}); - event_payloads_custom_profile_.push_back({{0xdf, 0x54, 0x1b, 0x06, 0xff, 0xff, 0x06, 0x32}}); - event_payloads_custom_profile_.push_back({{0xc6, 0x4f, 0x2a, 0x47, 0xff, 0xff, 0x07, 0x32}}); - event_payloads_custom_profile_.push_back({{0x41, 0xd7, 0x36, 0x88, 0xff, 0xff, 0x08, 0x32}}); - event_payloads_custom_profile_.push_back({{0x58, 0xcc, 0x07, 0xc9, 0xff, 0xff, 0x09, 0x32}}); - - received_responses_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID] = 0; - received_responses_counters_[0x8001] = 0; - received_responses_counters_[0x6543] = 0; - received_responses_counters_[0x8002] = 0; - - std::string test_remote("--remote"); - std::string test_local("--local"); - std::string test_allow_remote_client("--allow"); - std::string test_deny_remote_client("--deny"); - std::string help("--help"); - - int i = 1; - while (i < argc) - { - if(test_remote == argv[i]) - { - is_remote_test = true; - } - else if(test_local == argv[i]) - { - is_remote_test = false; - } - else if(test_allow_remote_client == argv[i]) - { - remote_client_allowed = true; - } - else if(test_deny_remote_client == argv[i]) - { - remote_client_allowed = false; - } - else if(help == argv[i]) - { - VSOMEIP_INFO << "Parameters:\n" - << "--remote: Run test between two hosts\n" - << "--local: Run test locally\n" - << "--allow: test is started with a policy that allows remote messages sent by this test client to the service\n" - << "--deny: test is started with a policy that denies remote messages sent by this test client to the service\n" - << "--help: print this help"; - } - i++; - } - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/e2e_tests/e2e_test_client.hpp b/test/e2e_tests/e2e_test_client.hpp deleted file mode 100644 index 378263c..0000000 --- a/test/e2e_tests/e2e_test_client.hpp +++ /dev/null @@ -1,55 +0,0 @@ - -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef E2E_TEST_CLIENT_HPP -#define E2E_TEST_CLIENT_HPP - -#include - -#include - -#include "../someip_test_globals.hpp" - -#include -#include -#include -#include - -class e2e_test_client { -public: - e2e_test_client(bool _test_external_communication, - bool _is_remote_client_allowed); - bool init(); - void start(); - void stop(); - - void on_state(vsomeip::state_type_e _state); - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available); - void on_message(const std::shared_ptr &_response); - - void run(); - void join_sender_thread(); - -private: - void shutdown_service(); - - std::shared_ptr app_; - - std::mutex mutex_; - std::condition_variable condition_; - bool is_available_; - - std::thread sender_; - - std::atomic received_responses_; - std::atomic received_allowed_events_; - - bool test_external_communication_; - bool is_remote_client_allowed_; -}; - -#endif // E2E_TEST_CLIENT_HPP diff --git a/test/e2e_tests/e2e_test_external_master_start.sh b/test/e2e_tests/e2e_test_external_master_start.sh deleted file mode 100755 index e787fcb..0000000 --- a/test/e2e_tests/e2e_test_external_master_start.sh +++ /dev/null @@ -1,74 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 1 ] -then - echo "Please pass a json file to this script" - echo "For example: $0 e2e_test_client_external.json" - exit 1 -fi - -MASTER_JSON_FILE=$1 -SERVICE_JSON_FILE=${MASTER_JSON_FILE/client/service} -ALLOW_DENY=$2 - -FAIL=0 - -export VSOMEIP_CONFIGURATION=$1 -export VSOMEIP_APPLICATION_NAME=client-sample -./e2e_test_client --remote & -PID_CLIENT=$! - - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting external e2e test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./e2e_test_external_slave_start.sh $SERVICE_JSON_FILE\"" & -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./e2e_test_external_slave_start.sh $SERVICE_JSON_FILE" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./e2e_test_external_slave_start.sh $SERVICE_JSON_FILE\" >> $WS_ROOT/slave_test_output 2>&1" & - -else -cat <> payloads_profile_01_; -std::vector> payloads_custom_profile_; -std::map received_requests_counters_; - -e2e_test_service::e2e_test_service() : - app_(vsomeip::runtime::get()->create_application()), - is_registered_(false), - blocked_(false), - number_of_received_messages_(0), - offer_thread_(std::bind(&e2e_test_service::run, this)) { -} - -bool e2e_test_service::init() { - std::lock_guard its_lock(mutex_); - - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - // profile01 CRC8 Method ID: 0x8421 - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, - std::bind(&e2e_test_service::on_message, this, - std::placeholders::_1)); - - // custom profile CRC32 Method ID: 0x6543 - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, 0x6543, - std::bind(&e2e_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, - std::bind(&e2e_test_service::on_message_shutdown, this, - std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&e2e_test_service::on_state, this, - std::placeholders::_1)); - - // offer field 0x8001 eventgroup 0x01 - std::set its_eventgroups; - its_eventgroups.insert(0x01); - - // offer field 0x8002 eventgroup 0x02 - std::set its_eventgroups_2; - its_eventgroups_2.insert(0x02); - - // profile01 CRC8 Event ID: 0x8001 - app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8001), its_eventgroups, - vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); - - // set value to field which gets filled by e2e protection with CRC on sending - // after e2e protection the payload for first event should look like: - // {{0xa4, 0xa1, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff} - std::shared_ptr its_payload = - vsomeip::runtime::get()->create_payload(); - vsomeip::byte_t its_data[8] = {0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; - its_payload->set_data(its_data, 8); - - app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8001), its_payload); - - // custom profile CRC32 Event ID: 0x8002 - app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8002), its_eventgroups_2, - vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); - - // set value to field which gets filled by e2e protection with CRC on sending - // after e2e protection the payload for first event should look like: - // {{0x89, 0x0e, 0xbc, 0x80, 0xff, 0xff, 0x00, 0x32} - std::shared_ptr its_payload_8002 = - vsomeip::runtime::get()->create_payload(); - vsomeip::byte_t its_data_8002[8] = {0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x32}; - its_payload_8002->set_data(its_data_8002, 8); - - app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8002), its_payload_8002); - - return true; -} - -void e2e_test_service::start() { - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void e2e_test_service::stop() { - VSOMEIP_INFO << "Stopping..."; - app_->clear_all_handler(); - app_->stop(); -} - -void e2e_test_service::join_offer_thread() { - if (offer_thread_.joinable()) { - offer_thread_.join(); - } -} - -void e2e_test_service::offer() { - app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void e2e_test_service::stop_offer() { - app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void e2e_test_service::on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : - "deregistered."); - - if(_state == vsomeip::state_type_e::ST_REGISTERED) { - if(!is_registered_) { - is_registered_ = true; - std::lock_guard its_lock(mutex_); - blocked_ = true; - // "start" the run method thread - condition_.notify_one(); - } - } - else { - is_registered_ = false; - } -} - -void e2e_test_service::on_message(const std::shared_ptr& _request) { - ASSERT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _request->get_service()); - ASSERT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _request->get_instance()); - - VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _request->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _request->get_session() << "] method: " << _request->get_method() ; - - std::shared_ptr its_response = - vsomeip::runtime::get()->create_response(_request); - std::shared_ptr< vsomeip::payload > its_vsomeip_payload = - vsomeip::runtime::get()->create_payload(); - std::shared_ptr its_event_payload = - vsomeip::runtime::get()->create_payload(); - - // send fixed payload for profile 01 CRC8 - if (_request->get_method() == vsomeip_test::TEST_SERVICE_METHOD_ID) { - its_vsomeip_payload->set_data(payloads_profile_01_[received_requests_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND]); - its_response->set_payload(its_vsomeip_payload); - app_->send(its_response); - - // set value to field which gets filled by e2e protection with CRC on sending - vsomeip::byte_t its_data[8] = {0x00, 0x00, (uint8_t)received_requests_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID], 0xff, 0xff, 0xff, 0xff, 0xff}; - its_event_payload->set_data(its_data, 8); - app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8001), its_event_payload); - received_requests_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID]++; - } else if (_request->get_method() == 0x6543) { - //send fixed payload for custom profile CRC32 - its_vsomeip_payload->set_data(payloads_custom_profile_[received_requests_counters_[0x6543] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND]); - its_response->set_payload(its_vsomeip_payload); - app_->send(its_response); - - // set value to field which gets filled by e2e protection with 4 byte CRC 32 on sending - vsomeip::byte_t its_data[8] = {0x00, 0x00, 0x00, 0x00, 0xff, 0xff, (uint8_t)received_requests_counters_[0x6543], 0x32}; - its_event_payload->set_data(its_data, 8); - app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8002), its_event_payload); - received_requests_counters_[0x6543]++; - } - - number_of_received_messages_++; - if(number_of_received_messages_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND * 2) { - VSOMEIP_INFO << "Received all messages!"; - } -} - -void e2e_test_service::on_message_shutdown( - const std::shared_ptr& _request) { - (void)_request; - VSOMEIP_INFO << "Shutdown method was called, going down now."; - stop(); -} - -void e2e_test_service::run() { - std::unique_lock its_lock(mutex_); - while (!blocked_) - condition_.wait(its_lock); - offer(); -} - -TEST(someip_e2e_test, basic_subscribe_request_response) { - e2e_test_service test_service; - if (test_service.init()) { - test_service.start(); - test_service.join_offer_thread(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) { - - /* - e2e profile01 CRC8 protected sample payloads using the following config at receiver: - "service_id" : "0x1234", - "event_id" : "0x8421", - "profile" : "CRC8", - "variant" : "checker", - "crc_offset" : "0", - "data_id_mode" : "3", - "data_length" : "56", - "data_id" : "0xA73" - */ - payloads_profile_01_.push_back({{0x82, 0xa4, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x39, 0xa8, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x87, 0xa4, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x3c, 0xa8, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x55, 0xac, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x82, 0xa4, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x39, 0xa8, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x87, 0xa4, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x3c, 0xa8, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); - payloads_profile_01_.push_back({{0x55, 0xac, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); - - /* - e2e custom profile CRC32 protected sample payloads using the following config at receiver: - "service_id" : "0x1234", - "event_id" : "0x6543", - "profile" : "CRC32", - "variant" : "checker", - "crc_offset" : "0" - */ - payloads_custom_profile_.push_back({{0xa4, 0xb2, 0x75, 0x1f, 0xff, 0x00, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa5, 0x70, 0x1f, 0x28, 0xff, 0x01, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa7, 0x36, 0xa1, 0x71, 0xff, 0x02, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa6, 0xf4, 0xcb, 0x46, 0xff, 0x03, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa3, 0xbb, 0xdd, 0xc3, 0xff, 0x04, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa2, 0x79, 0xb7, 0xf4, 0xff, 0x05, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa0, 0x3f, 0x09, 0xad, 0xff, 0x06, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xa1, 0xfd, 0x63, 0x9a, 0xff, 0x07, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xaa, 0xa1, 0x24, 0xa7, 0xff, 0x08, 0xff, 0x32}}); - payloads_custom_profile_.push_back({{0xab, 0x63, 0x4e, 0x90, 0xff, 0x09, 0xff, 0x32}}); - - received_requests_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID] = 0; - received_requests_counters_[0x7654] = 0; - received_requests_counters_[0x6543] = 0; - received_requests_counters_[0x5432] = 0; - - std::string test_remote("--remote"); - std::string test_local("--local"); - std::string test_allow_remote_client("--allow"); - std::string test_deny_remote_client("--deny"); - std::string help("--help"); - - int i = 1; - while (i < argc) - { - if(test_remote == argv[i]) - { - is_remote_test = true; - } - else if(test_local == argv[i]) - { - is_remote_test = false; - } - else if(test_allow_remote_client == argv[i]) - { - remote_client_allowed = true; - } - else if(test_deny_remote_client == argv[i]) - { - remote_client_allowed = false; - } - else if(help == argv[i]) - { - VSOMEIP_INFO << "Parameters:\n" - << "--remote: Run test between two hosts\n" - << "--local: Run test locally\n" - << "--allow: test is started with a policy that allows remote messages sent by this test client to the service\n" - << "--deny: test is started with a policy that denies remote messages sent by this test client to the service\n" - << "--help: print this help"; - } - i++; - } - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/e2e_tests/e2e_test_service.hpp b/test/e2e_tests/e2e_test_service.hpp deleted file mode 100644 index f7f2b96..0000000 --- a/test/e2e_tests/e2e_test_service.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef e2e_test_SERVICE_HPP -#define e2e_test_SERVICE_HPP - -#include - -#include - -#include "../someip_test_globals.hpp" - -#include -#include -#include - -class e2e_test_service { -public: - e2e_test_service(); - bool init(); - void start(); - void stop(); - void offer(); - void stop_offer(); - void join_offer_thread(); - void on_state(vsomeip::state_type_e _state); - void on_message(const std::shared_ptr &_request); - void on_message_shutdown(const std::shared_ptr &_request); - void run(); - -private: - std::shared_ptr app_; - bool is_registered_; - - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - std::uint32_t number_of_received_messages_; - std::thread offer_thread_; -}; - -#endif // E2E_TEST_SERVICE_HPP diff --git a/test/event_tests/conf/event_test_master.json.in b/test/event_tests/conf/event_test_master.json.in deleted file mode 100644 index b8db14f..0000000 --- a/test/event_tests/conf/event_test_master.json.in +++ /dev/null @@ -1,32 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications" : - [ - { - "name" : "event_test_client", - "id" : "0x3489", - "max_dispatch_time" : "1000" - } - ], - "routing":"routingmanagerd", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.50.1", - "port":"30490", - "protocol":"udp", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/event_tests/conf/event_test_slave_tcp.json.in b/test/event_tests/conf/event_test_slave_tcp.json.in deleted file mode 100644 index d0bbed9..0000000 --- a/test/event_tests/conf/event_test_slave_tcp.json.in +++ /dev/null @@ -1,43 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications" : - [ - { - "name" : "event_test_service", - "id" : "0x1210", - "max_dispatch_time" : "1000" - } - ], - "services": - [ - { - "service":"0x3344", - "instance":"0x0001", - "reliable": { - "port":"40001", - "enable-magic-cookies":"false" - } - } - ], - "routing":"routingmanagerd", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.50.1", - "port":"30490", - "protocol":"udp", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/event_tests/conf/event_test_slave_udp.json.in b/test/event_tests/conf/event_test_slave_udp.json.in deleted file mode 100644 index 6bf693b..0000000 --- a/test/event_tests/conf/event_test_slave_udp.json.in +++ /dev/null @@ -1,40 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications" : - [ - { - "name" : "event_test_service", - "id" : "0x1210", - "max_dispatch_time" : "1000" - } - ], - "services": - [ - { - "service":"0x3344", - "instance":"0x0001", - "unreliable":"30001" - } - ], - "routing":"routingmanagerd", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.50.1", - "port":"30490", - "protocol":"udp", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/event_tests/event_test_client.cpp b/test/event_tests/event_test_client.cpp deleted file mode 100644 index 227de85..0000000 --- a/test/event_tests/event_test_client.cpp +++ /dev/null @@ -1,282 +0,0 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "event_test_globals.hpp" - -class event_test_client { -public: - event_test_client(struct event_test::service_info _service_info, event_test::test_mode_e _mode, - bool _use_tcp) : - service_info_(_service_info), - test_mode_(_mode), - use_tcp_(_use_tcp), - app_(vsomeip::runtime::get()->create_application("event_test_client")), - service_available_(false), - wait_until_registered_(true), - wait_until_service_available_(true), - wait_until_subscription_accepted_(true), - wait_until_events_received_(true), - wait_until_shutdown_reply_received_(true), - number_events_to_send_(50), - number_events_received_(0), - send_thread_(std::bind(&event_test_client::send, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&event_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, - std::bind(&event_test_client::on_message, this, - std::placeholders::_1)); - - // register availability for all other services and request their event. - app_->register_availability_handler(service_info_.service_id, - service_info_.instance_id, - std::bind(&event_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - app_->request_service(service_info_.service_id, - service_info_.instance_id); - - std::set its_eventgroups; - its_eventgroups.insert(service_info_.eventgroup_id); - app_->request_event(service_info_.service_id, - service_info_.instance_id, service_info_.event_id, - its_eventgroups, vsomeip::event_type_e::ET_EVENT, - (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); - app_->register_subscription_status_handler(service_info_.service_id, - service_info_.instance_id, service_info_.eventgroup_id, - service_info_.event_id, - std::bind(&event_test_client::on_subscription_status_changed, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4, - std::placeholders::_5)); - app_->subscribe(service_info_.service_id, service_info_.instance_id, - service_info_.eventgroup_id); - - app_->start(); - } - - ~event_test_client() { - send_thread_.join(); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - VSOMEIP_INFO << "Service [" << std::setw(4) - << std::setfill('0') << std::hex << _service << "." << _instance - << "] is " << (_is_available ? "available":"not available") << "."; - if (_is_available) { - std::lock_guard its_lock(mutex_); - wait_until_service_available_ = false; - condition_.notify_one(); - } - } - - void on_message(const std::shared_ptr &_message) { - if(_message->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - on_notification(_message); - } else if (_message->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - on_response(_message); - } - } - - void on_notification(const std::shared_ptr &_message) { - EXPECT_EQ(service_info_.service_id, _message->get_service()); - EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - EXPECT_EQ(service_info_.event_id, _message->get_method()); - if (test_mode_ == event_test::test_mode_e::PAYLOAD_FIXED) { - EXPECT_EQ(event_test::payload_fixed_length, _message->get_payload()->get_length()); - } else if (test_mode_ == event_test::test_mode_e::PAYLOAD_DYNAMIC) { - static vsomeip::length_t length_last_received_msg(0); - EXPECT_GT(_message->get_payload()->get_length(), length_last_received_msg); - length_last_received_msg = _message->get_payload()->get_length(); - - } - if (++number_events_received_ == number_events_to_send_) { - std::lock_guard its_lock(mutex_); - wait_until_events_received_ = false; - condition_.notify_one(); - } - - VSOMEIP_DEBUG - << "Received a notification with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_session() << "] from Service/Method [" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_service() << "/" << std::setw(4) << std::setfill('0') - << std::hex << _message->get_method() <<"]"; - - } - - void on_response(const std::shared_ptr &_message) { - EXPECT_EQ(service_info_.service_id, _message->get_service()); - EXPECT_EQ(service_info_.shutdown_method_id, _message->get_method()); - EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - std::lock_guard its_lock(mutex_); - wait_until_shutdown_reply_received_ = false; - condition_.notify_one(); - } - - void on_subscription_status_changed(const vsomeip::service_t _service, - const vsomeip::instance_t _instance, - const vsomeip::eventgroup_t _eventgroup, - const vsomeip::event_t _event, - const uint16_t error_code) { - EXPECT_EQ(service_info_.service_id, _service); - EXPECT_EQ(service_info_.instance_id, _instance); - EXPECT_EQ(service_info_.eventgroup_id, _eventgroup); - EXPECT_EQ(service_info_.event_id, _event); - EXPECT_TRUE((error_code == 0x0u || error_code == 0x7u)); - if (error_code == 0x0u) { // accepted - std::lock_guard its_lock(mutex_); - wait_until_subscription_accepted_ = false; - condition_.notify_one(); - } - } - - void send() { - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - while (wait_until_service_available_) { - condition_.wait(its_lock); - } - - while (wait_until_subscription_accepted_) { - if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { - VSOMEIP_ERROR << "Subscription wasn't accepted in time!"; - break; - } - } - - // call notify method - auto its_message = vsomeip::runtime::get()->create_request(use_tcp_); - its_message->set_service(service_info_.service_id); - its_message->set_instance(service_info_.instance_id); - its_message->set_method(service_info_.notify_method_id); - its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); - auto its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data(std::vector({ - static_cast(test_mode_), - static_cast(number_events_to_send_)})); - its_message->set_payload(its_payload); - app_->send(its_message); - - while (wait_until_events_received_) { - if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { - VSOMEIP_ERROR << "Didn't receive events in time!"; - break; - } - } - - // shutdown service - its_message->set_method(service_info_.shutdown_method_id); - its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST); - app_->send(its_message); - - while (wait_until_shutdown_reply_received_) { - if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { - VSOMEIP_ERROR << "Shutdown request wasn't answered in time!"; - break; - } - } - VSOMEIP_INFO << "going down"; - app_->clear_all_handler(); - app_->stop(); - } - - -private: - struct event_test::service_info service_info_; - event_test::test_mode_e test_mode_; - bool use_tcp_; - std::shared_ptr app_; - bool service_available_; - - bool wait_until_registered_; - bool wait_until_service_available_; - bool wait_until_subscription_accepted_; - bool wait_until_events_received_; - bool wait_until_shutdown_reply_received_; - std::mutex mutex_; - std::condition_variable condition_; - - const std::uint8_t number_events_to_send_; - std::atomic number_events_received_; - std::thread send_thread_; -}; - -static event_test::test_mode_e passed_mode = event_test::test_mode_e::PAYLOAD_FIXED; -static bool use_tcp = false; - -TEST(someip_event_test, subscribe_or_call_method_at_service) -{ - event_test_client its_sample(event_test::service, passed_mode, use_tcp); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if (argc < 3) { - std::cerr << "Please specify a operation mode, like: " << argv[0] << "PAYLOAD_FIXED TCP" << std::endl; - std::cerr << "Valid operation modes are PAYLOAD_FIXED and PAYLOAD_DYNAMIC" << std::endl; - std::cerr << "Valid communication modes are UDP or TCP" << std::endl; - return 1; - } - - if (std::string("PAYLOAD_FIXED") == std::string(argv[1])) { - passed_mode = event_test::test_mode_e::PAYLOAD_FIXED; - } else if (std::string("PAYLOAD_DYNAMIC") == std::string(argv[1])) { - passed_mode = event_test::test_mode_e::PAYLOAD_DYNAMIC; - } else { - std::cerr << "Wrong operation mode passed, exiting" << std::endl; - std::cerr << "Please specify a operation mode, like: " << argv[0] << " PAYLOAD_FIXED" << std::endl; - std::cerr << "Valid operation modes are PAYLOAD_FIXED and PAYLOAD_DYNAMIC" << std::endl; - return 1; - } - if (std::string("TCP")== std::string(argv[2])) { - use_tcp = true; - } else if (std::string("UDP")== std::string(argv[2])) { - use_tcp = false; - } - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/event_tests/event_test_globals.hpp b/test/event_tests/event_test_globals.hpp deleted file mode 100644 index 733c3c6..0000000 --- a/test/event_tests/event_test_globals.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EVENT_TEST_GLOBALS_HPP_ -#define EVENT_TEST_GLOBALS_HPP_ - -namespace event_test { - -struct service_info { - vsomeip::service_t service_id; - vsomeip::instance_t instance_id; - vsomeip::method_t method_id; - vsomeip::event_t event_id; - vsomeip::eventgroup_t eventgroup_id; - vsomeip::method_t shutdown_method_id; - vsomeip::method_t notify_method_id; -}; - -struct service_info service = { 0x3344, 0x1, 0x1111, 0x8002, 0x1, 0x1404, 0x4242 }; - -enum test_mode_e : std::uint8_t { - UNKNOWN, - PAYLOAD_FIXED, - PAYLOAD_DYNAMIC -}; - -std::uint32_t payload_fixed_length = 20; - -} - -#endif /* EVENT_TEST_GLOBALS_HPP_ */ diff --git a/test/event_tests/event_test_master_starter.sh b/test/event_tests/event_test_master_starter.sh deleted file mode 100755 index e00639f..0000000 --- a/test/event_tests/event_test_master_starter.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -FAIL=0 - -if [ $# -lt 2 ] -then - echo "Please pass a operation and communication mode to this script." - echo "For example: $0 PAYLOAD_FIXED UDP" - echo "Valid operation modes include [PAYLOAD_FIXED, PAYLOAD_DYNAMIC]" - echo "Valid communication modes include [UDP, TCP]" - exit 1 -fi -TESTMODE=$1 -COMMUNICATIONMODE=$2 - -export VSOMEIP_CONFIGURATION=event_test_master.json -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -./event_test_client $TESTMODE $COMMUNICATIONMODE & -PID_CLIENT=$! - -sleep 1 - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting offer test on slave LXC offer_test_external_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./event_test_slave_starter.sh $COMMUNICATIONMODE\"" & -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && sleep 10; ./event_test_slave_starter.sh $COMMUNICATIONMODE" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./event_test_slave_starter.sh $COMMUNICATIONMODE\" >> $WS_ROOT/slave_test_output 2>&1" & - -else -cat < -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "event_test_globals.hpp" - -class event_test_service { -public: - event_test_service(struct event_test::service_info _service_info, bool _use_tcp) : - service_info_(_service_info), - test_mode_(event_test::test_mode_e::UNKNOWN), - app_(vsomeip::runtime::get()->create_application("event_test_service")), - wait_until_registered_(true), - wait_until_notify_method_called_(true), - wait_until_shutdown_method_called_(true), - client_subscribed_(false), - notifications_to_send_(0), - offer_thread_(std::bind(&event_test_service::run, this)), - use_tcp_(_use_tcp) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&event_test_service::on_state, this, - std::placeholders::_1)); - - std::set its_eventgroups; - its_eventgroups.insert(_service_info.eventgroup_id); - app_->offer_event(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_eventgroups, - vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), - false, true, nullptr, - (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.shutdown_method_id, - std::bind(&event_test_service::on_shutdown_method_called, this, - std::placeholders::_1)); - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.notify_method_id, - std::bind(&event_test_service::on_message, this, - std::placeholders::_1)); - app_->register_subscription_handler(service_info_.service_id, - service_info_.instance_id, service_info_.eventgroup_id, - std::bind(&event_test_service::subscription_handler, - this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4)); - - app_->start(); - } - - ~event_test_service() { - offer_thread_.join(); - } - - void offer() { - app_->offer_service(service_info_.service_id, service_info_.instance_id); - } - - void stop() { - app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); - app_->clear_all_handler(); - app_->stop(); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_shutdown_method_called(const std::shared_ptr &_message) { - app_->send(vsomeip::runtime::get()->create_response(_message)); - VSOMEIP_WARNING << "************************************************************"; - VSOMEIP_WARNING << "Shutdown method called -> going down!"; - VSOMEIP_WARNING << "************************************************************"; - std::lock_guard its_lock(mutex_); - wait_until_shutdown_method_called_ = false; - condition_.notify_one(); - } - - void on_message(const std::shared_ptr &_message) { - EXPECT_EQ(service_info_.service_id, _message->get_service()); - EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - EXPECT_EQ(service_info_.notify_method_id, _message->get_method()); - auto its_payload = _message->get_payload(); - ASSERT_EQ(2u, its_payload->get_length()); - test_mode_ = static_cast(its_payload->get_data()[0]); - notifications_to_send_ = static_cast(its_payload->get_data()[1]); - std::lock_guard its_lock(mutex_); - wait_until_notify_method_called_ = false; - condition_.notify_one(); - } - - void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - - while (wait_until_notify_method_called_) { - condition_.wait(its_lock); - } - VSOMEIP_INFO << "notify"; - notify(); - - - while (wait_until_shutdown_method_called_) { - condition_.wait(its_lock); - } - its_lock.unlock(); - stop(); - } - - void notify() { - EXPECT_TRUE(client_subscribed_); - auto its_payload = vsomeip::runtime::get()->create_payload(); - for (std::uint32_t i = 0; i < notifications_to_send_; i++) { - if (test_mode_ == event_test::test_mode_e::PAYLOAD_FIXED) { - its_payload->set_data(std::vector(event_test::payload_fixed_length, 0x44)); - } else if (test_mode_ == event_test::test_mode_e::PAYLOAD_DYNAMIC) { - its_payload->set_data(std::vector(i+1, 0x55)); - } - app_->notify(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_payload, false); - } - } - - bool subscription_handler(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) { - (void)_uid; - (void)_gid; - VSOMEIP_INFO << __func__ << ": client: 0x" << std::hex << _client - << ((_subscribed) ? " subscribed" : "unsubscribed"); - client_subscribed_ = _subscribed; - return true; - } - -private: - struct event_test::service_info service_info_; - event_test::test_mode_e test_mode_; - std::shared_ptr app_; - - bool wait_until_registered_; - bool wait_until_notify_method_called_; - bool wait_until_shutdown_method_called_; - std::atomic client_subscribed_; - std::uint32_t notifications_to_send_; - std::mutex mutex_; - std::condition_variable condition_; - std::thread offer_thread_; - bool use_tcp_; -}; - -static bool use_tcp = false; - -TEST(someip_event_test, send_events) -{ - event_test_service its_sample(event_test::service, use_tcp); -} - - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - - if (std::string("TCP")== std::string(argv[1])) { - use_tcp = true; - } else if (std::string("UDP")== std::string(argv[1])) { - use_tcp = false; - } - - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/event_tests/event_test_slave_starter.sh b/test/event_tests/event_test_slave_starter.sh deleted file mode 100755 index c09bd79..0000000 --- a/test/event_tests/event_test_slave_starter.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -FAIL=0 - -if [ $# -lt 1 ] -then - echo "Please pass a operation and communication mode to this script." - echo "For example: $0 UDP" - echo "Valid communication modes include [UDP, TCP]" - exit 1 -fi -COMMUNICATIONMODE=$1 - -if [ "$COMMUNICATIONMODE" = "TCP" ]; then - export VSOMEIP_CONFIGURATION=event_test_slave_tcp.json -elif [ "$COMMUNICATIONMODE" = "UDP" ]; then - export VSOMEIP_CONFIGURATION=event_test_slave_udp.json -fi - - -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -./event_test_service $COMMUNICATIONMODE & -PID_SERVICE=$! - -# Wait until all clients and services are finished -for job in $PID_SERVICE -do - # Fail gets incremented if a client exits with a non-zero exit code - echo "waiting for $job" - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill $PID_VSOMEIPD -sleep 1 - -# Check if everything went well -exit $FAIL diff --git a/test/header_factory_tests/header_factory_test.cpp b/test/header_factory_tests/header_factory_test.cpp deleted file mode 100644 index bcd1ef3..0000000 --- a/test/header_factory_tests/header_factory_test.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include - -#include - -#include "../someip_test_globals.hpp" - -class someip_header_factory_test: public ::testing::Test -{ -protected: - std::shared_ptr request_; - std::shared_ptr response_; - std::shared_ptr notification_; - std::shared_ptr app_; - std::shared_ptr message_; - - vsomeip::service_t service_id_ = vsomeip_test::TEST_SERVICE_SERVICE_ID; - vsomeip::method_t method_id_ = vsomeip_test::TEST_SERVICE_METHOD_ID; - vsomeip::instance_t instance_id_ = vsomeip_test::TEST_SERVICE_INSTANCE_ID; - vsomeip::interface_version_t interface_version_ = 0x01; - vsomeip::client_t client_id_ = vsomeip_test::TEST_CLIENT_CLIENT_ID; - vsomeip::session_t session_id_ = vsomeip_test::TEST_INITIAL_SESSION_ID; -}; - -TEST_F(someip_header_factory_test, create_request_test) -{ - ASSERT_TRUE(request_.get() == nullptr); - request_ = vsomeip::runtime::get()->create_request(); - - // check that returned shared_ptr is not null - ASSERT_TRUE(request_.get() != nullptr); - - // Check the protocol version - // this shall be set to 0x01 according to the spec. TR_SOMEIP_00052 - ASSERT_EQ(request_->get_protocol_version(), 0x01); - // Check the message type - // this shall be 0x00 (REQUEST) according to the spec. TR_SOMEIP_00055 - ASSERT_EQ(request_->get_message_type(), vsomeip::message_type_e::MT_REQUEST); - // Check the return code - // this shall be 0x00 (E_OK) according to the spec. TR_SOMEIP_00058 - ASSERT_EQ(request_->get_return_code(), vsomeip::return_code_e::E_OK); - -} - -TEST_F(someip_header_factory_test, create_request_and_response_test) -{ - ASSERT_TRUE(request_.get() == nullptr); - request_ = vsomeip::runtime::get()->create_request(); - // check that returned shared_ptr is not null - ASSERT_TRUE(request_.get() != nullptr); - - request_->set_service(service_id_); - request_->set_method(method_id_); - request_->set_interface_version(interface_version_); - // set the request_id (client_id + session_id). This normally is set by the - // application_impl::send() if a request is send, we set it here to test the - // correct initialization of the response - request_->set_client(client_id_); - request_->set_session(session_id_); - - ASSERT_TRUE(response_.get() == nullptr); - response_ = vsomeip::runtime::get()->create_response(request_); - // check that returned shared_ptr is not null - ASSERT_TRUE(response_.get() != nullptr); - - ASSERT_EQ(response_->get_service(), request_->get_service()); - ASSERT_EQ(response_->get_method(), request_->get_method()); - ASSERT_EQ(response_->get_session(), request_->get_session()); - - // length? --> gets only set if a payload is added - - ASSERT_EQ(response_->get_protocol_version(), request_->get_protocol_version()); - ASSERT_EQ(response_->get_interface_version(), request_->get_interface_version()); - - // Check the message type - // this shall be 0x00 (REQUEST) according to the spec. TR_SOMEIP_00055 - ASSERT_EQ(request_->get_message_type(), vsomeip::message_type_e::MT_REQUEST); - - // Check the message type - // this shall be 0x80 (RESPONSE) according to the spec. TR_SOMEIP_00055 - ASSERT_EQ(response_->get_message_type(), vsomeip::message_type_e::MT_RESPONSE); - - // Check the return code - // this shall be 0x00 (E_OK) according to the spec. TR_SOMEIP_00058 - // and TR_SOMEIP_00191 - ASSERT_EQ(response_->get_return_code(), vsomeip::return_code_e::E_OK); - -} - -TEST_F(someip_header_factory_test, create_notification_test) -{ - ASSERT_TRUE(notification_.get() == nullptr); - notification_ = vsomeip::runtime::get()->create_notification(); - - // check that returned shared_ptr is not null - ASSERT_TRUE(notification_.get() != nullptr); - - // Check the protocol version - // this shall be set to 0x01 according to the spec. TR_SOMEIP_00052 - ASSERT_EQ(notification_->get_protocol_version(), 0x01); - // Check the message type - // this shall be 0x02 (NOTIFICATION) according to the spec. TR_SOMEIP_00055 - ASSERT_EQ(notification_->get_message_type(), vsomeip::message_type_e::MT_NOTIFICATION); - // Check the return code - // this shall be 0x00 (E_OK) according to the spec. TR_SOMEIP_00058 - ASSERT_EQ(notification_->get_return_code(), vsomeip::return_code_e::E_OK); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/header_factory_tests/header_factory_test_client.cpp b/test/header_factory_tests/header_factory_test_client.cpp deleted file mode 100644 index 3ac4a06..0000000 --- a/test/header_factory_tests/header_factory_test_client.cpp +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "header_factory_test_client.hpp" - -header_factory_test_client::header_factory_test_client(bool _use_tcp) : - app_(vsomeip::runtime::get()->create_application()), - request_(vsomeip::runtime::get()->create_request(_use_tcp)), - blocked_(false), - is_available_(false), - number_of_messages_to_send_(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND), - number_of_sent_messages_(0), - number_of_acknowledged_messages_(0), - sender_(std::bind(&header_factory_test_client::run, this)) -{ -} - -bool header_factory_test_client::init() -{ - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - - app_->register_state_handler( - std::bind(&header_factory_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, - std::bind(&header_factory_test_client::on_message, this, - std::placeholders::_1)); - - app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - std::bind(&header_factory_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - return true; -} - -void header_factory_test_client::start() -{ - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void header_factory_test_client::stop() -{ - VSOMEIP_INFO << "Stopping..."; - app_->clear_all_handler(); - app_->stop(); -} - -void header_factory_test_client::join_sender_thread(){ - sender_.join(); - - ASSERT_EQ(number_of_sent_messages_, number_of_acknowledged_messages_); -} - -void header_factory_test_client::on_state(vsomeip::state_type_e _state) -{ - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); - } -} - -void header_factory_test_client::on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) -{ - VSOMEIP_INFO << "Service [" << std::setw(4) << std::setfill('0') << std::hex - << _service << "." << _instance << "] is " - << (_is_available ? "available." : "NOT available."); - - if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service - && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) - { - if(is_available_ && !_is_available) - { - is_available_ = false; - } - else if(_is_available && !is_available_) - { - is_available_ = true; - send(); - } - } -} - -void header_factory_test_client::on_message(const std::shared_ptr& _response) -{ - VSOMEIP_INFO << "Received a response from Service [" << std::setw(4) - << std::setfill('0') << std::hex << _response->get_service() << "." - << std::setw(4) << std::setfill('0') << std::hex - << _response->get_instance() << "] to Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex - << _response->get_client() << "/" << std::setw(4) - << std::setfill('0') << std::hex << _response->get_session() << "]"; - number_of_acknowledged_messages_++; - ASSERT_EQ(_response->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID); - ASSERT_EQ(_response->get_instance(), vsomeip_test::TEST_SERVICE_INSTANCE_ID); - ASSERT_EQ(_response->get_session(), - static_cast(number_of_acknowledged_messages_)); - if(number_of_acknowledged_messages_ == number_of_messages_to_send_) { - std::lock_guard its_lock(mutex_); - blocked_ = true; - condition_.notify_one(); - } -} - -void header_factory_test_client::send() -{ - std::lock_guard its_lock(mutex_); - blocked_ = true; - condition_.notify_one(); -} - -void header_factory_test_client::run() -{ - std::unique_lock its_lock(mutex_); - while (!blocked_) - { - condition_.wait(its_lock); - } - blocked_ = false; - request_->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - request_->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - request_->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); - - for (uint32_t i = 0; i < number_of_messages_to_send_; i++) - { - app_->send(request_); - VSOMEIP_INFO << "Client/Session [" << std::setw(4) << std::setfill('0') - << std::hex << request_->get_client() << "/" << std::setw(4) - << std::setfill('0') << std::hex << request_->get_session() - << "] sent a request to Service [" << std::setw(4) - << std::setfill('0') << std::hex << request_->get_service() - << "." << std::setw(4) << std::setfill('0') << std::hex - << request_->get_instance() << "]"; - number_of_sent_messages_++; - } - // wait until all messages have been acknowledged - while (!blocked_) - { - condition_.wait(its_lock); - } - stop(); -} - -TEST(someip_header_factory_test, send_message_ten_times_test) -{ - bool use_tcp = false; - header_factory_test_client test_client_(use_tcp); - if (test_client_.init()) { - test_client_.start(); - test_client_.join_sender_thread(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/header_factory_tests/header_factory_test_client.hpp b/test/header_factory_tests/header_factory_test_client.hpp deleted file mode 100644 index 8e9a4c2..0000000 --- a/test/header_factory_tests/header_factory_test_client.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef HEADERFACTORYTESTCLIENT_HPP_ -#define HEADERFACTORYTESTCLIENT_HPP_ - -#include - -#include - -#include -#include -#include -#include - -#include "../someip_test_globals.hpp" - -class header_factory_test_client -{ -public: - header_factory_test_client(bool _use_tcp); - bool init(); - void start(); - void stop(); - void join_sender_thread(); - void on_state(vsomeip::state_type_e _state); - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available); - void on_message(const std::shared_ptr &_response); - void send(); - void run(); - -private: - std::shared_ptr app_; - std::shared_ptr request_; - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - bool is_available_; - std::uint32_t number_of_messages_to_send_; - std::uint32_t number_of_sent_messages_; - std::uint32_t number_of_acknowledged_messages_; - std::thread sender_; -}; - -#endif /* HEADERFACTORYTESTCLIENT_HPP_ */ diff --git a/test/header_factory_tests/header_factory_test_client.json b/test/header_factory_tests/header_factory_test_client.json deleted file mode 100644 index 71bc75b..0000000 --- a/test/header_factory_tests/header_factory_test_client.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "unicast" : "127.0.0.1", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "true", - "path" : "/var/log/vsomeip.log" - }, - - "dlt" : "true" - }, - - "applications" : - [ - { - "name" : "header_factory_test_client", - "id" : "0x1343" - } - ], - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678", - "unreliable" : "30509", - "events" : - [ - { - "event" : "0x0777", - "is_field" : "true" - }, - - { - "event" : "0x0778", - "is_field" : "false" - }, - - { - "event" : "0x0779", - "is_field" : "true" - } - ], - - "eventgroups" : - [ - { - "eventgroup" : "0x4455", - "events" : - [ - "0x777", - "0x778" - ] - }, - - { - "eventgroup" : "0x4465", - "events" : - [ - "0x778", - "0x779" - ], - - "is_multicast" : "true" - }, - - { - "eventgroup" : "0x4555", - "events" : - [ - "0x777", - "0x779" - ] - } - ] - } - ], - - "routing" : "header_factory_test_service", - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30491", - "protocol" : "udp", - "initial_delay_min" : "10", - "initial_delay_max" : "100", - "repetitions_base_delay" : "200", - "repetitions_max" : "3", - "ttl" : "3", - "cyclic_offer_delay" : "2000", - "request_response_delay" : "1500" - } -} \ No newline at end of file diff --git a/test/header_factory_tests/header_factory_test_client_start.sh b/test/header_factory_tests/header_factory_test_client_start.sh deleted file mode 100755 index 4e9c1ed..0000000 --- a/test/header_factory_tests/header_factory_test_client_start.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. -export VSOMEIP_APPLICATION_NAME=header_factory_test_client -export VSOMEIP_CONFIGURATION=header_factory_test_client.json -./header_factory_test_client diff --git a/test/header_factory_tests/header_factory_test_send_receive_starter.sh b/test/header_factory_tests/header_factory_test_send_receive_starter.sh deleted file mode 100755 index 5d1d780..0000000 --- a/test/header_factory_tests/header_factory_test_send_receive_starter.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -# Start the service -export VSOMEIP_APPLICATION_NAME=header_factory_test_service -export VSOMEIP_CONFIGURATION=header_factory_test_service.json -./header_factory_test_service & -sleep 1; - -# Start the client -export VSOMEIP_APPLICATION_NAME=header_factory_test_client -export VSOMEIP_CONFIGURATION=header_factory_test_client.json -./header_factory_test_client & - -# Wait until client and service are finished -FAIL=0 -for job in $(jobs -p) -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if client and server both exited sucessfully -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/header_factory_tests/header_factory_test_service.cpp b/test/header_factory_tests/header_factory_test_service.cpp deleted file mode 100644 index d60c743..0000000 --- a/test/header_factory_tests/header_factory_test_service.cpp +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "header_factory_test_service.hpp" - -#include - -header_factory_test_service::header_factory_test_service(bool _use_static_routing) : - app_(vsomeip::runtime::get()->create_application()), - is_registered_(false), - use_static_routing_(_use_static_routing), - blocked_(false), - number_of_received_messages_(0), - offer_thread_(std::bind(&header_factory_test_service::run, this)) -{ -} - -bool header_factory_test_service::init() -{ - std::lock_guard its_lock(mutex_); - - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, - std::bind(&header_factory_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&header_factory_test_service::on_state, this, - std::placeholders::_1)); - - VSOMEIP_INFO << "Static routing " << (use_static_routing_ ? "ON" : "OFF"); - return true; -} - -void header_factory_test_service::start() -{ - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void header_factory_test_service::stop() -{ - VSOMEIP_INFO << "Stopping..."; - app_->clear_all_handler(); - app_->stop(); - std::thread t([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 5));}); - t.join(); -} - -void header_factory_test_service::join_offer_thread() -{ - offer_thread_.join(); -} - -void header_factory_test_service::offer() -{ - app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void header_factory_test_service::stop_offer() -{ - app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void header_factory_test_service::on_state(vsomeip::state_type_e _state) -{ - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : - "deregistered."); - - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - if(!is_registered_) - { - is_registered_ = true; - std::lock_guard its_lock(mutex_); - blocked_ = true; - // "start" the run method thread - condition_.notify_one(); - } - } - else - { - is_registered_ = false; - } -} - -void header_factory_test_service::on_message(const std::shared_ptr& _request) -{ - VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _request->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _request->get_session() << "]"; - - number_of_received_messages_++; - - ASSERT_EQ(_request->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID); - ASSERT_EQ(_request->get_method(), vsomeip_test::TEST_SERVICE_METHOD_ID); - - // Check the protocol version this shall be set to 0x01 according to the spec. - // TR_SOMEIP_00052 - ASSERT_EQ(_request->get_protocol_version(), 0x01); - // Check the message type this shall be 0xx (REQUEST) according to the spec. - // TR_SOMEIP_00055 - ASSERT_EQ(_request->get_message_type(), vsomeip::message_type_e::MT_REQUEST); - - // check the session id. - ASSERT_EQ(_request->get_session(), static_cast(number_of_received_messages_)); - - - // send response - std::shared_ptr its_response = - vsomeip::runtime::get()->create_response(_request); - - app_->send(its_response); - - if(number_of_received_messages_ >= vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND) - { - std::lock_guard its_lock(mutex_); - blocked_ =true; - condition_.notify_one(); - } - ASSERT_LT(number_of_received_messages_, - vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND + 1); -} - -void header_factory_test_service::run() -{ - std::unique_lock its_lock(mutex_); - while (!blocked_) - condition_.wait(its_lock); - - blocked_ = false; - if(use_static_routing_) - { - offer(); - } - while (!blocked_) - condition_.wait(its_lock); - - std::thread t([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 5));}); - t.join(); - app_->stop(); -} - -TEST(someip_header_factory_test, reveice_message_ten_times_test) -{ - bool use_static_routing = true; - header_factory_test_service test_service(use_static_routing); - if (test_service.init()) { - test_service.start(); - test_service.join_offer_thread(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/header_factory_tests/header_factory_test_service.hpp b/test/header_factory_tests/header_factory_test_service.hpp deleted file mode 100644 index 32e49e5..0000000 --- a/test/header_factory_tests/header_factory_test_service.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef HEADERFACTORYTESTSERVICE_HPP_ -#define HEADERFACTORYTESTSERVICE_HPP_ -#include - -#include - -#include -#include -#include -#include - -#include "../someip_test_globals.hpp" - -class header_factory_test_service -{ -public: - header_factory_test_service(bool _use_static_routing); - bool init(); - void start(); - void stop(); - void offer(); - void stop_offer(); - void join_offer_thread(); - void on_state(vsomeip::state_type_e _state); - void on_message(const std::shared_ptr &_request); - void run(); - -private: - std::shared_ptr app_; - bool is_registered_; - bool use_static_routing_; - - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - std::uint32_t number_of_received_messages_; - std::thread offer_thread_; -}; - -#endif /* HEADERFACTORYTESTSERVICE_HPP_ */ diff --git a/test/header_factory_tests/header_factory_test_service.json b/test/header_factory_tests/header_factory_test_service.json deleted file mode 100644 index a99d0a2..0000000 --- a/test/header_factory_tests/header_factory_test_service.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "unicast" : "127.0.0.1", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "false", - "path" : "/tmp/vsomeip.log" - }, - "dlt" : "false" - }, - - "applications" : - [ - { - "name" : "header_factory_test_service", - "id" : "0x1277" - } - ], - - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678", - "unreliable" : "30509", - "multicast" : - { - "address" : "224.225.226.233", - "port" : "32344" - }, - - "events" : - [ - { - "event" : "0x0777", - "is_field" : "true", - "update-cycle" : 2000 - }, - - { - "event" : "0x0778", - "is_field" : "true", - "update-cycle" : 0 - }, - - { - "event" : "0x0779", - "is_field" : "true" - } - ], - - "eventgroups" : - [ - { - "eventgroup" : "0x4455", - "events" : - [ - "0x777", - "0x778" - ] - }, - - { - "eventgroup" : "0x4465", - "events" : - [ - "0x778", - "0x779" - ], - - "is_multicast" : "true" - }, - - { - "eventgroup" : "0x4555", - "events" : - [ - "0x777", - "0x779" - ] - } - ] - } - ], - - "routing" : "header_factory_test_service", - - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp", - "initial_delay_min" : "10", - "initial_delay_max" : "100", - "repetitions_base_delay" : "200", - "repetitions_max" : "3", - "ttl" : "3", - "cyclic_offer_delay" : "2000", - "request_response_delay" : "1500" - } -} \ No newline at end of file diff --git a/test/header_factory_tests/header_factory_test_service_start.sh b/test/header_factory_tests/header_factory_test_service_start.sh deleted file mode 100755 index e123a46..0000000 --- a/test/header_factory_tests/header_factory_test_service_start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=header_factory_test_service -export VSOMEIP_CONFIGURATION=header_factory_test_service.json -./header_factory_test_service diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master.json.in deleted file mode 100644 index d7b5c7b..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master.json.in +++ /dev/null @@ -1,81 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_one", - "id":"0x1111" - }, - { - "name":"initial_event_test_service_two", - "id":"0x2222" - }, - { - "name":"initial_event_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30001", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30002", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30003", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x8888", - "instance":"0x0001", - "unreliable":"8888" - } - ], - "routing":"initial_event_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in deleted file mode 100644 index a05d13f..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in +++ /dev/null @@ -1,78 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_one", - "id":"0x1111" - }, - { - "name":"initial_event_test_service_two", - "id":"0x2222" - }, - { - "name":"initial_event_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x8888", - "instance":"0x0001", - "unreliable":"8888" - } - ], - "routing":"initial_event_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_udp.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_udp.json.in deleted file mode 100644 index 8ce06f0..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_udp.json.in +++ /dev/null @@ -1,66 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_one", - "id":"0x1111" - }, - { - "name":"initial_event_test_service_two", - "id":"0x2222" - }, - { - "name":"initial_event_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30001" - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30002" - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30003" - }, - { - "service":"0x8888", - "instance":"0x0001", - "unreliable":"8888" - } - ], - "routing":"initial_event_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json.in deleted file mode 100644 index 6445025..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json.in +++ /dev/null @@ -1,81 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_one", - "id":"0x1111" - }, - { - "name":"initial_event_test_service_two", - "id":"0x2222" - }, - { - "name":"initial_event_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30001", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1111", - "instance":"0x0002", - "unreliable":"30002", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x1111", - "instance":"0x0003", - "unreliable":"30003", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x8888", - "instance":"0x0001", - "unreliable":"8888" - } - ], - "routing":"initial_event_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json.in deleted file mode 100644 index c5dddc3..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json.in +++ /dev/null @@ -1,82 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "diagnosis" : "0x63", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_four", - "id":"0x4444" - }, - { - "name":"initial_event_test_service_five", - "id":"0x5555" - }, - { - "name":"initial_event_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30004", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0002", - "unreliable":"30005", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0003", - "unreliable":"30006", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x9999", - "instance":"0x0001", - "unreliable":"9999" - } - ], - "routing":"initial_event_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave.json.in deleted file mode 100644 index 3e7e286..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave.json.in +++ /dev/null @@ -1,82 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "diagnosis" : "0x63", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_four", - "id":"0x4444" - }, - { - "name":"initial_event_test_service_five", - "id":"0x5555" - }, - { - "name":"initial_event_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30004", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30005", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30006", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x9999", - "instance":"0x0001", - "unreliable":"9999" - } - ], - "routing":"initial_event_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in deleted file mode 100644 index 1fc97a4..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in +++ /dev/null @@ -1,79 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "diagnosis" : "0x63", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_four", - "id":"0x4444" - }, - { - "name":"initial_event_test_service_five", - "id":"0x5555" - }, - { - "name":"initial_event_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x9999", - "instance":"0x0001", - "unreliable":"9999" - } - ], - "routing":"initial_event_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_udp.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_udp.json.in deleted file mode 100644 index d303a4c..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_udp.json.in +++ /dev/null @@ -1,67 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "diagnosis" : "0x63", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_four", - "id":"0x4444" - }, - { - "name":"initial_event_test_service_five", - "id":"0x5555" - }, - { - "name":"initial_event_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30004" - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30005" - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30006" - }, - { - "service":"0x9999", - "instance":"0x0001", - "unreliable":"9999" - } - ], - "routing":"initial_event_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_master.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_master.json.in deleted file mode 100644 index f168fae..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_master.json.in +++ /dev/null @@ -1,81 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_one", - "id":"0x1111" - }, - { - "name":"initial_event_test_service_two", - "id":"0x2222" - }, - { - "name":"initial_event_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x8888", - "instance":"0x0001", - "unreliable":"8888" - } - ], - "routing":"initial_event_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_slave.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_slave.json.in deleted file mode 100644 index 30206a2..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_slave.json.in +++ /dev/null @@ -1,82 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "diagnosis" : "0x63", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_four", - "id":"0x4444" - }, - { - "name":"initial_event_test_service_five", - "id":"0x5555" - }, - { - "name":"initial_event_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x9999", - "instance":"0x0001", - "unreliable":"9999" - } - ], - "routing":"initial_event_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master.json.in deleted file mode 100644 index 785e651..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master.json.in +++ /dev/null @@ -1,81 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_one", - "id":"0x1111" - }, - { - "name":"initial_event_test_service_two", - "id":"0x2222" - }, - { - "name":"initial_event_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x8888", - "instance":"0x0001", - "unreliable":"8888" - } - ], - "routing":"initial_event_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in deleted file mode 100644 index b065685..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in +++ /dev/null @@ -1,78 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_one", - "id":"0x1111" - }, - { - "name":"initial_event_test_service_two", - "id":"0x2222" - }, - { - "name":"initial_event_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x8888", - "instance":"0x0001", - "unreliable":"8888" - } - ], - "routing":"initial_event_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_udp.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_udp.json.in deleted file mode 100644 index ca77daf..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_udp.json.in +++ /dev/null @@ -1,66 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_one", - "id":"0x1111" - }, - { - "name":"initial_event_test_service_two", - "id":"0x2222" - }, - { - "name":"initial_event_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30000" - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30000" - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30000" - }, - { - "service":"0x8888", - "instance":"0x0001", - "unreliable":"8888" - } - ], - "routing":"initial_event_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave.json.in deleted file mode 100644 index cfbdac4..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave.json.in +++ /dev/null @@ -1,82 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "diagnosis" : "0x63", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_four", - "id":"0x4444" - }, - { - "name":"initial_event_test_service_five", - "id":"0x5555" - }, - { - "name":"initial_event_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x9999", - "instance":"0x0001", - "unreliable":"9999" - } - ], - "routing":"initial_event_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in deleted file mode 100644 index eaeab4a..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in +++ /dev/null @@ -1,79 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "diagnosis" : "0x63", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_four", - "id":"0x4444" - }, - { - "name":"initial_event_test_service_five", - "id":"0x5555" - }, - { - "name":"initial_event_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x9999", - "instance":"0x0001", - "unreliable":"9999" - } - ], - "routing":"initial_event_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_udp.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_udp.json.in deleted file mode 100644 index 5d978f0..0000000 --- a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_udp.json.in +++ /dev/null @@ -1,67 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "diagnosis" : "0x63", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_four", - "id":"0x4444" - }, - { - "name":"initial_event_test_service_five", - "id":"0x5555" - }, - { - "name":"initial_event_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30000" - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30000" - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30000" - }, - { - "service":"0x9999", - "instance":"0x0001", - "unreliable":"9999" - } - ], - "routing":"initial_event_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_master.json.in b/test/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_master.json.in deleted file mode 100644 index d7b5c7b..0000000 --- a/test/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_master.json.in +++ /dev/null @@ -1,81 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_one", - "id":"0x1111" - }, - { - "name":"initial_event_test_service_two", - "id":"0x2222" - }, - { - "name":"initial_event_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30001", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30002", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30003", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x8888", - "instance":"0x0001", - "unreliable":"8888" - } - ], - "routing":"initial_event_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_slave.json.in b/test/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_slave.json.in deleted file mode 100644 index facc51a..0000000 --- a/test/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_slave.json.in +++ /dev/null @@ -1,82 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "diagnosis" : "0x63", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_four", - "id":"0x1111" - }, - { - "name":"initial_event_test_service_five", - "id":"0x2222" - }, - { - "name":"initial_event_test_service_six", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30004", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30005", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30006", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x9999", - "instance":"0x0001", - "unreliable":"9999" - } - ], - "routing":"initial_event_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_master.json.in b/test/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_master.json.in deleted file mode 100644 index 785e651..0000000 --- a/test/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_master.json.in +++ /dev/null @@ -1,81 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_one", - "id":"0x1111" - }, - { - "name":"initial_event_test_service_two", - "id":"0x2222" - }, - { - "name":"initial_event_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x8888", - "instance":"0x0001", - "unreliable":"8888" - } - ], - "routing":"initial_event_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_slave.json.in b/test/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_slave.json.in deleted file mode 100644 index 97b5d9f..0000000 --- a/test/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_slave.json.in +++ /dev/null @@ -1,82 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "diagnosis" : "0x63", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"initial_event_test_service_four", - "id":"0x1111" - }, - { - "name":"initial_event_test_service_five", - "id":"0x2222" - }, - { - "name":"initial_event_test_service_six", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x9999", - "instance":"0x0001", - "unreliable":"9999" - } - ], - "routing":"initial_event_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/initial_event_tests/initial_event_test_availability_checker.cpp b/test/initial_event_tests/initial_event_test_availability_checker.cpp deleted file mode 100644 index 4fc3085..0000000 --- a/test/initial_event_tests/initial_event_test_availability_checker.cpp +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "initial_event_test_globals.hpp" - - -class initial_event_test_availability_checker { -public: - initial_event_test_availability_checker(int _client_number, - std::array _service_infos) : - client_number_(_client_number), - service_infos_(_service_infos), - app_(vsomeip::runtime::get()->create_application()), - wait_until_registered_(true), - wait_for_stop_(true), - stop_thread_(std::bind(&initial_event_test_availability_checker::wait_for_stop, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&initial_event_test_availability_checker::on_state, this, - std::placeholders::_1)); - - // register availability for all other services and request their event. - for(const auto& i : service_infos_) { - if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) { - continue; - } - other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; - app_->register_availability_handler(i.service_id, i.instance_id, - std::bind(&initial_event_test_availability_checker::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - app_->request_service(i.service_id, i.instance_id); - } - - app_->start(); - } - - ~initial_event_test_availability_checker() { - stop_thread_.join(); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - if(_is_available) { - auto its_service = other_services_available_.find(std::make_pair(_service, _instance)); - if(its_service != other_services_available_.end()) { - if(its_service->second != _is_available) { - its_service->second = true; - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] Service [" - << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance - << "] is available."; - - } - } - - if(std::all_of(other_services_available_.cbegin(), - other_services_available_.cend(), - [](const std::map, bool>::value_type& v) { - return v.second;})) { - - std::lock_guard its_lock(stop_mutex_); - wait_for_stop_ = false; - stop_condition_.notify_one(); - } - } - } - - void wait_for_stop() { - std::unique_lock its_lock(stop_mutex_); - while (wait_for_stop_) { - stop_condition_.wait(its_lock); - } - VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] all services are available. Going down"; - app_->clear_all_handler(); - app_->stop(); - } - -private: - int client_number_; - std::array service_infos_; - std::shared_ptr app_; - std::map, bool> other_services_available_; - - bool wait_until_registered_; - std::mutex mutex_; - std::condition_variable condition_; - - bool wait_for_stop_; - std::mutex stop_mutex_; - std::condition_variable stop_condition_; - std::thread stop_thread_; -}; - -static int client_number; -static bool use_same_service_id; - -TEST(someip_initial_event_test, wait_for_availability_and_exit) -{ - if(use_same_service_id) { - initial_event_test_availability_checker its_sample(client_number, - initial_event_test::service_infos_same_service_id); - } else { - initial_event_test_availability_checker its_sample(client_number, - initial_event_test::service_infos); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if(argc < 2) { - std::cerr << "Please specify a client number and subscription type, like: " << argv[0] << " 2 SAME_SERVICE_ID" << std::endl; - std::cerr << "Valid client numbers are from 0 to 0xFFFF" << std::endl; - std::cerr << "If SAME_SERVICE_ID is specified as third parameter the test is run w/ multiple instances of the same service" << std::endl; - return 1; - } - - client_number = std::stoi(std::string(argv[1]), nullptr); - - if (argc >= 2) { - for (int i = 2; i < argc; i++) { - if (std::string("SAME_SERVICE_ID") == std::string(argv[i])) { - use_same_service_id = true; - std::cout << "Availability checker: Using same service ID" << std::endl; - } - } - } - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/initial_event_tests/initial_event_test_client.cpp b/test/initial_event_tests/initial_event_test_client.cpp deleted file mode 100644 index ef215f1..0000000 --- a/test/initial_event_tests/initial_event_test_client.cpp +++ /dev/null @@ -1,638 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifndef _WIN32 -#include -#endif - -#include -#include - -#include "initial_event_test_globals.hpp" - -class initial_event_test_client; -static initial_event_test_client* the_client; -extern "C" void signal_handler(int _signum); - -class initial_event_test_client { -public: - initial_event_test_client(int _client_number, - bool _service_offered_tcp_and_udp, - std::array _service_infos, - bool _subscribe_on_available, std::uint32_t _events_to_subscribe, - bool _initial_event_strict_checking, - bool _dont_exit, bool _subscribe_only_one, - vsomeip::reliability_type_e _reliability_type, - bool _client_subscribes_twice) : - client_number_(_client_number), - service_infos_(_service_infos), - service_offered_tcp_and_udp_(_service_offered_tcp_and_udp), - app_(vsomeip::runtime::get()->create_application()), - wait_until_registered_(true), - wait_for_stop_(true), - is_first(true), - subscribe_on_available_(_subscribe_on_available), - events_to_subscribe_(_events_to_subscribe), - initial_event_strict_checking_(_initial_event_strict_checking), - dont_exit_(_dont_exit), - subscribe_only_one_(_subscribe_only_one), - stop_thread_(&initial_event_test_client::wait_for_stop, this), - wait_for_signal_handler_registration_(true), - reliability_type_(_reliability_type), - client_subscribes_twice_(_client_subscribes_twice) - { - if (!app_->init()) { - stop_thread_.detach(); - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - - app_->register_state_handler( - std::bind(&initial_event_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, - std::bind(&initial_event_test_client::on_message, this, - std::placeholders::_1)); - - // register availability for all other services and request their event. - for(const auto& i : service_infos_) { - if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) { - continue; - } - app_->register_availability_handler(i.service_id, i.instance_id, - std::bind(&initial_event_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - app_->request_service(i.service_id, i.instance_id); - - std::set its_eventgroups; - its_eventgroups.insert(i.eventgroup_id); - for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) { - app_->request_event(i.service_id, i.instance_id, - static_cast(i.event_id + j), - its_eventgroups, vsomeip::event_type_e::ET_FIELD, - reliability_type_); - } - - other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; - - if (!subscribe_on_available_) { - if (events_to_subscribe_ == 1) { - app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, - vsomeip::DEFAULT_MAJOR); - - std::lock_guard its_lock(received_notifications_mutex_); - other_services_received_notification_[std::make_pair(i.service_id, i.event_id)] = 0; - } else if (events_to_subscribe_ > 1) { - if (!subscribe_only_one_) { - for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) { - app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, - vsomeip::DEFAULT_MAJOR, - static_cast(i.event_id + j)); - std::lock_guard its_lock(received_notifications_mutex_); - other_services_received_notification_[std::make_pair(i.service_id, i.event_id + j)] = 0; - } - } else { - app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, - vsomeip::DEFAULT_MAJOR, - static_cast(i.event_id)); - other_services_received_notification_[std::make_pair(i.service_id, i.event_id)] = 0; - } - } - } else { - for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) { - other_services_received_notification_[std::make_pair(i.service_id, i.event_id + j)] = 0; - } - } - } - - // Block all signals - sigset_t mask; - sigfillset(&mask); - pthread_sigmask(SIG_BLOCK, &mask, NULL); - // start thread which handles all of the signals - signal_thread_ = std::thread(&initial_event_test_client::wait_for_signal, this); - { - std::unique_lock its_lock(signal_mutex_); - while(wait_for_signal_handler_registration_) { - EXPECT_EQ(std::cv_status::no_timeout, - signal_condition_.wait_for(its_lock, std::chrono::seconds(10))); - } - wait_for_signal_handler_registration_ = true; - } - - app_->start(); - } - - ~initial_event_test_client() { - if (stop_thread_.joinable()) { - stop_thread_.join(); - } - if (signal_thread_.joinable()) { - signal_thread_.join(); - } - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - if(_is_available) { - auto its_service = other_services_available_.find(std::make_pair(_service, _instance)); - if(its_service != other_services_available_.end()) { - if(its_service->second != _is_available) { - its_service->second = true; - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] Service [" - << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance - << "] is available."; - - } - } - - if(std::all_of(other_services_available_.cbegin(), - other_services_available_.cend(), - [](const std::map, bool>::value_type& v) { - return v.second;})) { - VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] all services are available."; - if (subscribe_on_available_) { - for(const auto& i : service_infos_) { - if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) { - continue; - } - if (events_to_subscribe_ == 1 ) { - app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, - vsomeip::DEFAULT_MAJOR); - } else if (events_to_subscribe_ > 1) { - for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) { - app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, - vsomeip::DEFAULT_MAJOR, - static_cast(i.event_id + j)); - } - } - } - } - } - } - } - - void on_message(const std::shared_ptr &_message) { - if(_message->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - - { - std::lock_guard its_lock(received_notifications_mutex_); - other_services_received_notification_[std::make_pair(_message->get_service(), - _message->get_method())]++; - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] " - << "Received a notification with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_session() << "] from Service/Method [" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_service() << "/" << std::setw(4) << std::setfill('0') - << std::hex << _message->get_method() <<"] (now have: " - << std::dec << other_services_received_notification_[std::make_pair(_message->get_service(), - _message->get_method())] << ")"; - } - - std::shared_ptr its_payload(_message->get_payload()); - EXPECT_EQ(2u, its_payload->get_length()); - EXPECT_EQ((_message->get_service() & 0xFF00 ) >> 8, its_payload->get_data()[0]); - EXPECT_EQ((_message->get_service() & 0xFF), its_payload->get_data()[1]); - bool notify(false); - if (client_subscribes_twice_) { - // only relevant for testcase: - // initial_event_test_diff_client_ids_same_ports_udp_client_subscribes_twice - // check that a second subscribe triggers another initial event - // expect notifications_to_send_after_double_subscribe == 2; - if (is_first) { - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); - for(const auto& i : service_infos_) { - // subscribe again and expect initial events cached at rm::proxy to be received - // as configured routing manager only fires the event once after first susbcribe. - if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) { - continue; - } - if (!subscribe_on_available_) { - if (events_to_subscribe_ == 1) { - app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, - vsomeip::DEFAULT_MAJOR); - } else if (events_to_subscribe_ > 1) { - if (!subscribe_only_one_) { - for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) { - app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, - vsomeip::DEFAULT_MAJOR, - static_cast(i.event_id + j)); - } - } else { - app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, - vsomeip::DEFAULT_MAJOR, - static_cast(i.event_id)); - } - } - } - } - is_first = false; - } else { - bool received_initial_event_twice(false); - std::lock_guard its_lock(received_notifications_mutex_); - received_initial_event_twice = all_notifications_received_twice(); - if (received_initial_event_twice) { - notify = true; - } - } - } else { - if (!service_offered_tcp_and_udp_) { - std::lock_guard its_lock(received_notifications_mutex_); - if (all_notifications_received()) { - notify = true; - } - } else { - if (all_notifications_received_tcp_and_udp()) { - notify = true; - } - } - } - - if (notify && !dont_exit_) { - std::lock_guard its_lock(stop_mutex_); - wait_for_stop_ = false; - stop_condition_.notify_one(); - } - } - } - - bool all_notifications_received() { - return std::all_of( - other_services_received_notification_.cbegin(), - other_services_received_notification_.cend(), - [&](const std::map, std::uint32_t>::value_type& v) - { - bool result; - if (v.second == initial_event_test::notifications_to_send) { - result = true; - } else { - if (v.second >= initial_event_test::notifications_to_send) { - VSOMEIP_WARNING - << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] " - << " Received multiple initial events from service/instance: " - << std::setw(4) << std::setfill('0') << std::hex << v.first.first - << "." - << std::setw(4) << std::setfill('0') << std::hex << v.first.second - << " number of received events: " << v.second - << ". This is caused by StopSubscribe/Subscribe messages and/or" - << " service offered via UDP and TCP"; - if (initial_event_strict_checking_) { - ADD_FAILURE() << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] " - << " Received multiple initial events from service/instance: " - << std::setw(4) << std::setfill('0') << std::hex << v.first.first - << "." - << std::setw(4) << std::setfill('0') << std::hex << v.first.second - << " number of received events: " << v.second; - } - result = initial_event_strict_checking_ ? false : true; - - } else { - result = false; - } - } - - return result; - } - ); - } - - bool all_notifications_received_twice() { - return std::all_of( - other_services_received_notification_.cbegin(), - other_services_received_notification_.cend(), - [&](const std::map, std::uint32_t>::value_type& v) - { - bool result; - if (v.second == initial_event_test::notifications_to_send * 2) { - result = true; - } else { - if (v.second >= initial_event_test::notifications_to_send * 2) { - VSOMEIP_WARNING - << __func__ << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] " - << " Received multiple initial events from service/instance: " - << std::setw(4) << std::setfill('0') << std::hex << v.first.first - << "." - << std::setw(4) << std::setfill('0') << std::hex << v.first.second - << " number of received events: " << v.second - << ". This is caused by StopSubscribe/Subscribe messages and/or" - << " service offered via UDP and TCP"; - if (initial_event_strict_checking_) { - ADD_FAILURE() << __func__ << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] " - << " Received multiple initial events from service/instance: " - << std::setw(4) << std::setfill('0') << std::hex << v.first.first - << "." - << std::setw(4) << std::setfill('0') << std::hex << v.first.second - << " number of received events: " << v.second; - } - result = initial_event_strict_checking_ ? false : true; - - } else { - result = false; - } - } - return result; - } - ); - } - - bool all_notifications_received_tcp_and_udp() { - std::lock_guard its_lock(received_notifications_mutex_); - std::uint32_t received_twice(0); - std::uint32_t received_normal(0); - for(const auto &v : other_services_received_notification_) { - if (!initial_event_strict_checking_ && - v.second > initial_event_test::notifications_to_send * 2) { - VSOMEIP_WARNING - << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] " - << " Received multiple initial events from service/instance: " - << std::setw(4) << std::setfill('0') << std::hex << v.first.first - << "." - << std::setw(4) << std::setfill('0') << std::hex << v.first.second - << ". This is caused by StopSubscribe/Subscribe messages and/or" - << " service offered via UDP and TCP"; - received_twice++; - } else if (initial_event_strict_checking_ && - v.second > initial_event_test::notifications_to_send * 2) { - ADD_FAILURE() << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] " - << " Received multiple initial events from service/instance: " - << std::setw(4) << std::setfill('0') << std::hex << v.first.first - << "." - << std::setw(4) << std::setfill('0') << std::hex << v.first.second - << " number of received events: " << v.second; - } else if (v.second == initial_event_test::notifications_to_send * 2) { - received_twice++; - } else if(v.second == initial_event_test::notifications_to_send) { - received_normal++; - } - } - - if( received_twice == ((service_infos_.size() - 1) * events_to_subscribe_)/ 2 - && received_normal == ((service_infos_.size() - 1) * events_to_subscribe_)/ 2) { - // routing manager stub receives the notification - // - twice from external nodes - // - and normal from all internal nodes - VSOMEIP_ERROR << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] " - << "Received notifications:" - << " Normal: " << received_normal - << " Twice: " << received_twice; - return true; - } else if (initial_event_strict_checking_ && ( - received_twice > ((service_infos_.size() - 1) * events_to_subscribe_)/ 2)) { - ADD_FAILURE() << "[" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ << "] " - << " Received too much initial events twice: " << received_twice; - } else if (received_normal == (events_to_subscribe_ * (service_infos_.size() - 1))) { - return true; - } - return false; - } - - void wait_for_signal() { - // register signal handler - the_client = this; - - sigset_t handler_mask; - sigemptyset(&handler_mask); - sigaddset(&handler_mask, SIGUSR1); - sigaddset(&handler_mask, SIGTERM); - sigaddset(&handler_mask, SIGINT); - sigaddset(&handler_mask, SIGABRT); - pthread_sigmask(SIG_UNBLOCK, &handler_mask, NULL); - - - struct sigaction sa_new, sa_old; - sa_new.sa_handler = signal_handler; - sa_new.sa_flags = 0; - sigemptyset(&sa_new.sa_mask); - ::sigaction(SIGUSR1, &sa_new, &sa_old); - ::sigaction(SIGINT, &sa_new, &sa_old); - ::sigaction(SIGTERM, &sa_new, &sa_old); - ::sigaction(SIGABRT, &sa_new, &sa_old); - - - - - { - std::lock_guard its_lock(signal_mutex_); - wait_for_signal_handler_registration_ = false; - signal_condition_.notify_one(); - } - while (wait_for_stop_) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - } - - void handle_signal(int _signum) { - (void)_signum; - std::lock_guard its_lock(stop_mutex_); - wait_for_stop_ = false; - stop_condition_.notify_one(); - } - - void wait_for_stop() { - static int its_call_number(0); - its_call_number++; - - { - std::unique_lock its_lock(stop_mutex_); - while (wait_for_stop_) { - stop_condition_.wait_for(its_lock, std::chrono::milliseconds(100)); - } - VSOMEIP_ERROR << "(" << std::dec << its_call_number << ") [" << std::setw(4) << std::setfill('0') << std::hex - << client_number_ - << "] Received notifications from all services, going down"; - } - for (const auto& i : service_infos_) { - if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) { - continue; - } - app_->unsubscribe(i.service_id, i.instance_id, i.eventgroup_id); - } - app_->clear_all_handler(); - app_->stop(); - } - -private: - int client_number_; - std::array service_infos_; - bool service_offered_tcp_and_udp_; - std::shared_ptr app_; - std::map, bool> other_services_available_; - std::mutex received_notifications_mutex_; - std::map, std::uint32_t> other_services_received_notification_; - - bool wait_until_registered_; - std::mutex mutex_; - std::condition_variable condition_; - - std::atomic wait_for_stop_; - std::atomic is_first; - - bool subscribe_on_available_; - std::uint32_t events_to_subscribe_; - bool initial_event_strict_checking_; - bool dont_exit_; - bool subscribe_only_one_; - - std::mutex stop_mutex_; - std::condition_variable stop_condition_; - std::thread stop_thread_; - bool wait_for_signal_handler_registration_; - std::mutex signal_mutex_; - std::condition_variable signal_condition_; - std::thread signal_thread_; - vsomeip::reliability_type_e reliability_type_; - bool client_subscribes_twice_; -}; - -static int client_number; -static bool service_offered_tcp_and_udp; -static bool use_same_service_id; -static bool subscribe_on_available; -static std::uint32_t subscribe_multiple_events; -static bool initial_event_strict_checking; -static bool dont_exit; -static bool subscribe_only_one; -static bool client_subscribes_twice; - -vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN; - - -extern "C" void signal_handler(int signum) { - the_client->handle_signal(signum); -} - -TEST(someip_initial_event_test, wait_for_initial_events_of_all_services) -{ - if(use_same_service_id) { - initial_event_test_client its_sample(client_number, - service_offered_tcp_and_udp, - initial_event_test::service_infos_same_service_id, - subscribe_on_available, subscribe_multiple_events, - initial_event_strict_checking, dont_exit, - subscribe_only_one, - reliability_type, - client_subscribes_twice); - } else { - initial_event_test_client its_sample(client_number, service_offered_tcp_and_udp, - initial_event_test::service_infos, subscribe_on_available, - subscribe_multiple_events, initial_event_strict_checking, dont_exit, - subscribe_only_one, - reliability_type, - client_subscribes_twice); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - // Block all signals - sigset_t mask; - sigfillset(&mask); - pthread_sigmask(SIG_BLOCK, &mask, NULL); - ::testing::InitGoogleTest(&argc, argv); - - if(argc < 2) { - std::cerr << "Please specify a client number, like: " << argv[0] << " 2 SUBSCRIBE_BEFORE_START SAME_SERVICE_ID" << std::endl; - std::cerr << "Valid client numbers are from 0 to 0xFFFF" << std::endl; - std::cerr << "After client number one/multiple of these flags can be specified:"; - std::cerr << " - SERVICE_OFFERED_TCP_AND_UDP flag. Set this if the service is offered via TCP and UDP" << std::endl; - std::cerr << " - Time of subscription, valid values: [SUBSCRIBE_ON_AVAILABILITY, SUBSCRIBE_BEFORE_START], default SUBSCRIBE_BEFORE_START" << std::endl; - std::cerr << " - SAME_SERVICE_ID flag. If set the test is run w/ multiple instances of the same service, default false" << std::endl; - std::cerr << " - MULTIPLE_EVENTS flag. If set the test will subscribe to multiple events in the eventgroup, default false" << std::endl; - std::cerr << " - STRICT_CHECKING flag. If set the test will only successfully finish if exactly the number of initial events were received (and not more). Default false" << std::endl; - std::cerr << " - DONT_EXIT flag. If set the test will not exit if all notifications have been received. Default false" << std::endl; - std::cerr << " - SUBSCRIBE_ONLY_ONE flag. If set the test will only subscribe to one event even if MULTIPLE_EVENTS is set. Default false" << std::endl; - return 1; - } - - client_number = std::stoi(std::string(argv[1]), nullptr); - - subscribe_on_available = false; - initial_event_strict_checking = false; - service_offered_tcp_and_udp = false; - use_same_service_id = false; - subscribe_multiple_events = 1; - dont_exit = false; - subscribe_only_one = false; - client_subscribes_twice = false; - if (argc > 2) { - for (int i = 2; i < argc; i++) { - if (std::string("SUBSCRIBE_ON_AVAILABILITY") == std::string(argv[i])) { - subscribe_on_available = true; - } else if (std::string("SUBSCRIBE_BEFORE_START") == std::string(argv[i])) { - subscribe_on_available = false; - } else if (std::string("SAME_SERVICE_ID") == std::string(argv[i])) { - use_same_service_id = true; - std::cout << "Using same service ID" << std::endl; - } else if (std::string("MULTIPLE_EVENTS") == std::string(argv[i])) { - subscribe_multiple_events = 5; - } else if (std::string("STRICT_CHECKING") == std::string(argv[i])) { - initial_event_strict_checking = true; - } else if (std::string("DONT_EXIT") == std::string(argv[i])) { - dont_exit = true; - } else if (std::string("SUBSCRIBE_ONLY_ONE") == std::string(argv[i])) { - subscribe_only_one = true; - } else if (std::string("TCP")== std::string(argv[i])) { - reliability_type = vsomeip::reliability_type_e::RT_RELIABLE; - std::cout << "Using reliability type RT_RELIABLE" << std::endl; - } else if (std::string("UDP")== std::string(argv[i])) { - reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE; - std::cout << "Using reliability type RT_UNRELIABLE" << std::endl; - } else if (std::string("TCP_AND_UDP")== std::string(argv[i])) { - reliability_type = vsomeip::reliability_type_e::RT_BOTH; - std::cout << "Using reliability type RT_BOTH" << std::endl; - } else if (std::string("CLIENT_SUBSCRIBES_TWICE")== std::string(argv[i])) { - client_subscribes_twice = true; - std::cout << "Testing for initial event after a second subscribe from same client CLIENT_SUBSCRIBES_TWICE" << std::endl; - } - } - } - - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/initial_event_tests/initial_event_test_globals.hpp b/test/initial_event_tests/initial_event_test_globals.hpp deleted file mode 100644 index ce69ea9..0000000 --- a/test/initial_event_tests/initial_event_test_globals.hpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ -#define SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ - -namespace initial_event_test { - -struct service_info { - vsomeip::service_t service_id; - vsomeip::instance_t instance_id; - vsomeip::method_t method_id; - vsomeip::event_t event_id; - vsomeip::eventgroup_t eventgroup_id; -}; - -static constexpr std::array service_infos = {{ - // placeholder to be consistent w/ client ids, service ids, app names - { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }, - // node 1 - { 0x1111, 0x1, 0x1111, 0x1111, 0x1000 }, - { 0x2222, 0x1, 0x2222, 0x2222, 0x2000 }, - { 0x3333, 0x1, 0x3333, 0x3333, 0x3000 }, - // node 2 - { 0x4444, 0x1, 0x4444, 0x4444, 0x4000 }, - { 0x5555, 0x1, 0x5555, 0x5555, 0x5000 }, - { 0x6666, 0x1, 0x6666, 0x6666, 0x6000 } -}}; - -static constexpr std::array service_infos_same_service_id = {{ - // placeholder to be consistent w/ client ids, service ids, app names - { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }, - // node 1 - { 0x1111, 0x1, 0x1111, 0x1111, 0x1000 }, - { 0x1111, 0x2, 0x2222, 0x2222, 0x2000 }, - { 0x1111, 0x3, 0x3333, 0x3333, 0x3000 }, - // node 2 - { 0x2222, 0x1, 0x4444, 0x4444, 0x4000 }, - { 0x2222, 0x2, 0x5555, 0x5555, 0x5000 }, - { 0x2222, 0x3, 0x6666, 0x6666, 0x6000 } -}}; - -static constexpr service_info stop_service_master = { 0x8888, 0x1, 0x8888, 0x0, 0x0 }; -static constexpr service_info stop_service_slave = { 0x9999, 0x1, 0x9999, 0x0, 0x0 }; - -static constexpr int notifications_to_send = 1; -} - -#endif /* SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ */ diff --git a/test/initial_event_tests/initial_event_test_master_starter.sh b/test/initial_event_tests/initial_event_test_master_starter.sh deleted file mode 100755 index 85607c4..0000000 --- a/test/initial_event_tests/initial_event_test_master_starter.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 1 ] -then - echo "Please pass a json file to this script." - echo "For example: $0 initial_event_test_diff_client_ids_diff_ports_master.json" - echo "To use the same service id but different instances on the node pass SAME_SERVICE_ID as third parameter" - echo "To ensure the first client only subscribes to one event pass SUBSCRIBE_ONLY_ONE as third/fourth parameter" - exit 1 -fi - -PASSED_JSON_FILE=$1 -# Remove processed options from $@ -shift 1 -REMAINING_OPTIONS="$@" - -print_starter_message () { - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting initial event test on slave LXC with params $CLIENT_JSON_FILE $REMAINING_OPTIONS" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./initial_event_test_slave_starter.sh $CLIENT_JSON_FILE $REMAINING_OPTIONS\"" & -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./initial_event_test_slave_starter.sh $CLIENT_JSON_FILE $REMAINING_OPTIONS" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./initial_event_test_slave_starter.sh $CLIENT_JSON_FILE $REMAINING_OPTIONS\" >> $WS_ROOT/slave_test_output 2>&1" & -else -cat < -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "initial_event_test_globals.hpp" - - -class initial_event_test_service { -public: - initial_event_test_service(struct initial_event_test::service_info _service_info, - std::uint32_t _events_to_offer, vsomeip::reliability_type_e _reliability_type) : - service_info_(_service_info), - app_(vsomeip::runtime::get()->create_application()), - wait_until_registered_(true), - events_to_offer_(_events_to_offer), - offer_thread_(std::bind(&initial_event_test_service::run, this)), - reliability_type_(_reliability_type) { - if (!app_->init()) { - offer_thread_.detach(); - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&initial_event_test_service::on_state, this, - std::placeholders::_1)); - - // offer field - std::set its_eventgroups; - its_eventgroups.insert(service_info_.eventgroup_id); - for (std::uint16_t i = 0; i < events_to_offer_; i++) { - app_->offer_event(service_info_.service_id, service_info_.instance_id, - static_cast(service_info_.event_id + i), - its_eventgroups, vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), false, true, nullptr, - reliability_type_); - } - - // set value to field - std::shared_ptr its_payload = - vsomeip::runtime::get()->create_payload(); - vsomeip::byte_t its_data[2] = {static_cast((service_info_.service_id & 0xFF00) >> 8), - static_cast((service_info_.service_id & 0xFF))}; - its_payload->set_data(its_data, 2); - for (std::uint16_t i = 0; i < events_to_offer_; i++) { - app_->notify(service_info_.service_id, service_info_.instance_id, - static_cast(service_info_.event_id + i), its_payload); - } - - app_->start(); - } - - ~initial_event_test_service() { - if (offer_thread_.joinable()) { - offer_thread_.join(); - } - } - - void offer() { - app_->offer_service(service_info_.service_id, service_info_.instance_id); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - } - -private: - initial_event_test::service_info service_info_; - std::shared_ptr app_; - - bool wait_until_registered_; - std::uint32_t events_to_offer_; - std::mutex mutex_; - std::condition_variable condition_; - std::thread offer_thread_; - vsomeip::reliability_type_e reliability_type_; -}; - -static unsigned long service_number; -static bool use_same_service_id; -static std::uint32_t offer_multiple_events; -vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN; - -TEST(someip_initial_event_test, set_field_once) -{ - if(use_same_service_id) { - initial_event_test_service its_sample( - initial_event_test::service_infos_same_service_id[service_number], offer_multiple_events, - reliability_type); - } else { - initial_event_test_service its_sample( - initial_event_test::service_infos[service_number], offer_multiple_events, - reliability_type); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if(argc < 2) { - std::cerr << "Please specify a service number and subscription type, like: " << argv[0] << " 2 SAME_SERVICE_ID" << std::endl; - std::cerr << "Valid service numbers are in the range of [1,6]" << std::endl; - std::cerr << "After the service number one/multiple of these flags can be specified:"; - std::cerr << " - SAME_SERVICE_ID flag. If set the test is run w/ multiple instances of the same service, default false" << std::endl; - std::cerr << " - MULTIPLE_EVENTS flag. If set the test will offer to multiple events in the eventgroup, default false" << std::endl; - return 1; - } - - service_number = std::stoul(std::string(argv[1]), nullptr); - - offer_multiple_events = 1; - use_same_service_id = false; - - if (argc > 2) { - for (int i = 2; i < argc; i++) { - if (std::string("SAME_SERVICE_ID") == std::string(argv[i])) { - use_same_service_id = true; - std::cout << "Using same service ID" << std::endl; - } else if (std::string("MULTIPLE_EVENTS") == std::string(argv[i])) { - offer_multiple_events = 5; - } else if (std::string("TCP")== std::string(argv[i])) { - reliability_type = vsomeip::reliability_type_e::RT_RELIABLE; - std::cout << "Using reliability type RT_RELIABLE" << std::endl; - } else if (std::string("UDP")== std::string(argv[i])) { - reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE; - std::cout << "Using reliability type RT_UNRELIABLE" << std::endl; - } else if (std::string("TCP_AND_UDP")== std::string(argv[i])) { - reliability_type = vsomeip::reliability_type_e::RT_BOTH; - std::cout << "Using reliability type RT_BOTH" << std::endl; - } - } - } - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/initial_event_tests/initial_event_test_slave_starter.sh b/test/initial_event_tests/initial_event_test_slave_starter.sh deleted file mode 100755 index 6f6bd40..0000000 --- a/test/initial_event_tests/initial_event_test_slave_starter.sh +++ /dev/null @@ -1,104 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 1 ] -then - echo "Please pass a json file to this script." - echo "For example: $0 initial_event_test_diff_client_ids_diff_ports_slave.json UDP" - echo "To use the same service id but different instances on the node pass SAME_SERVICE_ID as third parameter" - echo "To ensure the first client only subscribes to one event pass SUBSCRIBE_ONLY_ONE as third/fourth parameter" - exit 1 -fi - -PASSED_JSON_FILE=$1 -# Remove processed options from $@ -shift 1 -REMAINING_OPTIONS=$@ - -FAIL=0 - -export VSOMEIP_CONFIGURATION=$PASSED_JSON_FILE - -# Start the services -export VSOMEIP_APPLICATION_NAME=initial_event_test_service_four -./initial_event_test_service 4 $REMAINING_OPTIONS & -PID_SERVICE_FOUR=$! - -export VSOMEIP_APPLICATION_NAME=initial_event_test_service_five -./initial_event_test_service 5 $REMAINING_OPTIONS & -PID_SERVICE_FIVE=$! - -export VSOMEIP_APPLICATION_NAME=initial_event_test_service_six -./initial_event_test_service 6 $REMAINING_OPTIONS & -PID_SERVICE_SIX=$! - -sleep 3 - -unset VSOMEIP_APPLICATION_NAME - -# Array for client pids -CLIENT_PIDS=() - -# Start first client which subscribes remotely -./initial_event_test_client 9000 DONT_EXIT $REMAINING_OPTIONS & -FIRST_PID=$! - -# remove SUBSCRIBE_ONLY_ONCE parameter from $REMAINING_OPTIONS to ensure the -# following clients subscribe normaly -REMAINING_OPTIONS=${REMAINING_OPTIONS%SUBSCRIBE_ONLY_ONE} -REMAINING_OPTIONS=${REMAINING_OPTIONS#SUBSCRIBE_ONLY_ONE} - -# Start availability checker in order to wait until the services on the remote -# were started as well -./initial_event_test_availability_checker 1234 $REMAINING_OPTIONS & -PID_AVAILABILITY_CHECKER=$! - -# wait until the services on the remote node were started as well -wait $PID_AVAILABILITY_CHECKER -sleep 2; -for client_number in $(seq 9001 9011) -do - ./initial_event_test_client $client_number STRICT_CHECKING $REMAINING_OPTIONS & - CLIENT_PIDS+=($!) -done - -# Wait until all clients are finished -for job in ${CLIENT_PIDS[*]} -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# wait until all clients exited on master side -./initial_event_test_stop_service SLAVE & -PID_STOP_SERVICE=$! -wait $PID_STOP_SERVICE - -# shutdown the first client -kill $FIRST_PID -wait $FIRST_PID || FAIL=$(($FAIL+1)) - -# shutdown the services -kill $PID_SERVICE_SIX -kill $PID_SERVICE_FIVE -kill $PID_SERVICE_FOUR - -sleep 1 -echo "" - -# Check if both exited successfully -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/initial_event_tests/initial_event_test_stop_service.cpp b/test/initial_event_tests/initial_event_test_stop_service.cpp deleted file mode 100644 index 465c837..0000000 --- a/test/initial_event_tests/initial_event_test_stop_service.cpp +++ /dev/null @@ -1,286 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "initial_event_test_globals.hpp" - - -class initial_event_test_stop_service { -public: - initial_event_test_stop_service(struct initial_event_test::service_info _service_info, bool _is_master) : - service_info_(_service_info), - is_master_(_is_master), - app_(vsomeip::runtime::get()->create_application()), - wait_until_registered_(true), - wait_until_stop_service_other_node_available_(true), - wait_until_shutdown_method_called_(true), - offer_thread_(std::bind(&initial_event_test_stop_service::run, this)), - wait_for_stop_(true), - stop_thread_(std::bind(&initial_event_test_stop_service::wait_for_stop, this)), - called_other_node_(false) { - if (!app_->init()) { - offer_thread_.detach(); - stop_thread_.detach(); - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&initial_event_test_stop_service::on_state, this, - std::placeholders::_1)); - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.method_id, - std::bind(&initial_event_test_stop_service::on_shutdown_method_called, this, - std::placeholders::_1)); - - // register availability for all other services and request their event. - if (is_master_) { - app_->request_service( - initial_event_test::stop_service_slave.service_id, - initial_event_test::stop_service_slave.instance_id); - app_->register_availability_handler( - initial_event_test::stop_service_slave.service_id, - initial_event_test::stop_service_slave.instance_id, - std::bind(&initial_event_test_stop_service::on_availability, - this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - } else { - app_->request_service( - initial_event_test::stop_service_master.service_id, - initial_event_test::stop_service_master.instance_id); - app_->register_availability_handler( - initial_event_test::stop_service_master.service_id, - initial_event_test::stop_service_master.instance_id, - std::bind(&initial_event_test_stop_service::on_availability, - this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - } - app_->start(); - } - - ~initial_event_test_stop_service() { - if (offer_thread_.joinable()) { - offer_thread_.join(); - } - if (stop_thread_.joinable()) { - stop_thread_.join(); - } - } - - void offer() { - if (is_master_) { - app_->offer_service( - initial_event_test::stop_service_master.service_id, - initial_event_test::stop_service_master.instance_id); - } else { - app_->offer_service( - initial_event_test::stop_service_slave.service_id, - initial_event_test::stop_service_slave.instance_id); - } - } - - void stop_offer() { - if (is_master_) { - app_->stop_offer_service( - initial_event_test::stop_service_master.service_id, - initial_event_test::stop_service_master.instance_id); - } else { - app_->stop_offer_service( - initial_event_test::stop_service_slave.service_id, - initial_event_test::stop_service_slave.instance_id); - } - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - bool notify(false); - if(_is_available) { - VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Service [" - << std::setw(4) << std::setfill('0') << std::hex << _service - << "." << _instance << "] is available."; - if(is_master_) { - if(_service == initial_event_test::stop_service_slave.service_id - && _instance == initial_event_test::stop_service_slave.instance_id) { - notify = true; - } - } else { - if(_service == initial_event_test::stop_service_master.service_id - && _instance == initial_event_test::stop_service_master.instance_id) { - notify = true; - } - } - } - if (notify) { - std::lock_guard its_lock(availability_mutex_); - wait_until_stop_service_other_node_available_ = false; - availability_condition_.notify_one(); - } - } - - void on_shutdown_method_called(const std::shared_ptr &_message) { - if(_message->get_message_type() == vsomeip::message_type_e::MT_REQUEST_NO_RETURN) { - VSOMEIP_DEBUG << "Received a request with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_session() << "] shutdown method called"; - - - VSOMEIP_ERROR << "stop_service::" << __func__ - << ": (1)"; - std::lock_guard its_lock(stop_mutex_); - VSOMEIP_ERROR << "stop_service::" << __func__ - << ": (2)"; - wait_for_stop_ = false; - stop_condition_.notify_one(); - } - } - - void run() { - { - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - - { - std::unique_lock its_availability_lock(availability_mutex_); - while (wait_until_stop_service_other_node_available_) { - availability_condition_.wait(its_availability_lock); - } - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Calling shutdown method on remote side"; - - std::shared_ptr msg(vsomeip::runtime::get()->create_request()); - msg->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); - if(is_master_) { - msg->set_service(initial_event_test::stop_service_slave.service_id); - msg->set_instance(initial_event_test::stop_service_slave.instance_id); - msg->set_method(initial_event_test::stop_service_slave.method_id); - } else { - msg->set_service(initial_event_test::stop_service_master.service_id); - msg->set_instance(initial_event_test::stop_service_master.instance_id); - msg->set_method(initial_event_test::stop_service_master.method_id); - } - app_->send(msg); - called_other_node_ = true; - { - std::unique_lock its_lock(mutex_); - while (wait_until_shutdown_method_called_) { - condition_.wait(its_lock); - } - } - } - - void wait_for_stop() { - static int its_call_number(0); - its_call_number++; - - std::unique_lock its_lock(stop_mutex_); - while (wait_for_stop_) { - stop_condition_.wait(its_lock); - } - VSOMEIP_INFO << "(" << std::dec << its_call_number << ") [" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id - << "] shutdown method was called, going down"; - while(!called_other_node_) { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } - // let offer thread exit - { - std::lock_guard its_lock(mutex_); - wait_until_shutdown_method_called_ = false; - condition_.notify_one(); - } - app_->clear_all_handler(); - app_->stop(); - } - -private: - initial_event_test::service_info service_info_; - bool is_master_; - std::shared_ptr app_; - std::map, bool> other_services_available_; - std::map, std::uint32_t> other_services_received_notification_; - - bool wait_until_registered_; - bool wait_until_stop_service_other_node_available_; - bool wait_until_shutdown_method_called_; - std::mutex mutex_; - std::condition_variable condition_; - std::thread offer_thread_; - - std::mutex availability_mutex_; - std::condition_variable availability_condition_; - - std::atomic wait_for_stop_; - std::mutex stop_mutex_; - std::condition_variable stop_condition_; - std::thread stop_thread_; - - std::atomic called_other_node_; -}; - -static bool is_master = false; - -TEST(someip_initial_event_test, wait_for_stop_method_to_be_called) -{ - if(is_master) { - initial_event_test_stop_service its_sample(initial_event_test::stop_service_master, is_master); - } else { - initial_event_test_stop_service its_sample(initial_event_test::stop_service_slave, is_master); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if(argc < 2) { - std::cerr << "Please specify a valid type, like: " << argv[0] << " MASTER" << std::endl; - std::cerr << "Valid types are in the range of [MASTER,SLAVE]" << std::endl; - return 1; - } - - if (argc >= 2 && std::string("MASTER") == std::string(argv[1])) { - is_master = true; - } else if (argc >= 2 && std::string("SLAVE") == std::string(argv[1])){ - is_master = false; - } - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/internal_routing_disabled_acceptance_test/CMakeLists.txt b/test/internal_routing_disabled_acceptance_test/CMakeLists.txt new file mode 100644 index 0000000..c823350 --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.4...3.22) + +# Workaround for version range in cmake_minimum_required() before 3.12 +if(${CMAKE_VERSION} VERSION_LESS 3.12) + cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +endif() + +project(internal_routing_disabled_acceptance_test LANGUAGES CXX) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_INIT} -pedantic -Wall -Wconversion -Wextra") +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(THREADS_PREFER_PTHREAD_FLAG ON) + +find_package(Threads REQUIRED) +find_package(Boost 1.55 COMPONENTS system REQUIRED) + +add_executable(${PROJECT_NAME} applet.cpp client.cpp server.cpp main.cpp) +target_include_directories(${PROJECT_NAME} PRIVATE ${gtest_SOURCE_DIR}/include) +target_link_libraries(${PROJECT_NAME} PRIVATE gtest Threads::Threads vsomeip3 ${Boost_LIBRARIES}) + +enable_testing() +add_test(NAME ${PROJECT_NAME} COMMAND $) +add_dependencies(build_network_tests ${PROJECT_NAME}) +configure_file(vsomeip.json vsomeip.json COPYONLY) +set_property( + TEST ${PROJECT_NAME} + APPEND PROPERTY ENVIRONMENT + "LD_LIBRARY_PATH=$" + "VSOMEIP_CONFIGURATION=${CMAKE_CURRENT_BINARY_DIR}/vsomeip.json" +) +set_property( + TEST ${PROJECT_NAME} + APPEND PROPERTY TIMEOUT + 60 +) diff --git a/test/internal_routing_disabled_acceptance_test/applet.cpp b/test/internal_routing_disabled_acceptance_test/applet.cpp new file mode 100644 index 0000000..50bf41c --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/applet.cpp @@ -0,0 +1,44 @@ +#include "applet.hpp" + +#include +#include + +#include +#include + +applet::applet(std::string_view name) : application{vsomeip_v3::runtime::get()->create_application(std::string{name})} +{ + if(!this->application->init()) + { + using namespace std::string_literals; + throw std::runtime_error{__func__ + "(): vSomeIP application init failure"s}; + } + + this->async_start = std::async( + std::launch::async, + &vsomeip_v3::application::start, + this->application + ); + + this->application->register_state_handler( + [this](vsomeip_v3::state_type_e state){ + switch(state) + { + case vsomeip_v3::state_type_e::ST_REGISTERED: + return this->on_state_registered(); + case vsomeip_v3::state_type_e::ST_DEREGISTERED: + return this->on_state_deregistered(); + } + } + ); +} + +applet::~applet() +{ + this->application->clear_all_handler(); + this->application->stop(); + this->async_start.wait(); +} + +void applet::on_state_registered() {} +void applet::on_state_deregistered() {} diff --git a/test/internal_routing_disabled_acceptance_test/applet.hpp b/test/internal_routing_disabled_acceptance_test/applet.hpp new file mode 100644 index 0000000..d536dc0 --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/applet.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include +#include + +#include + +struct applet +{ +protected: + std::shared_ptr application; + + applet(std::string_view name); + virtual ~applet(); + +private: + std::future async_start; + + virtual void on_state_registered(); + virtual void on_state_deregistered(); +}; diff --git a/test/internal_routing_disabled_acceptance_test/client.cpp b/test/internal_routing_disabled_acceptance_test/client.cpp new file mode 100644 index 0000000..ff7be78 --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/client.cpp @@ -0,0 +1,152 @@ +#include "client.hpp" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "config.hpp" + +client::client() : applet{"client"}, counter_event_received{}, counter_method_request{}, counter_method_response{} +{ + this->application->register_message_handler( + config::SERVICE_ID, + config::INSTANCE_ID, + vsomeip_v3::ANY_METHOD, + [this](const std::shared_ptr& message){ + std::shared_ptr runtime = vsomeip_v3::runtime::get(); + std::shared_ptr payload = message->get_payload(); + + switch(message->get_message_type()) + { + case vsomeip_v3::message_type_e::MT_RESPONSE: + std::cout + << "received:\n" + << "\tservice: " << std::hex << message->get_service() << '\n' + << "\tinstance: " << std::hex << message->get_instance() << '\n' + << "\tmethod: " << std::hex << message->get_method() << '\n' + << "\tpayload: " << payload->get_data() << '\n'; + this->counter_method_response++; + break; + + case vsomeip_v3::message_type_e::MT_NOTIFICATION: + std::cout << "GOT NOTIFICATION\n"; + this->counter_event_received++; + [[fallthrough]]; + + default: + std::cout << "unhandled message type: " << unsigned(message->get_message_type()) << '\n'; + } + } + ); + + this->application->register_availability_handler( + config::SERVICE_ID, + config::INSTANCE_ID, + [this](vsomeip_v3::service_t service, vsomeip_v3::instance_t instance, bool available){ + std::cout + << __func__ << '(' + << std::hex << service << ", " + << std::hex << instance << ", " + << std::boolalpha << available << ")\n"; + + if(service != config::SERVICE_ID) + return; + if(instance != config::INSTANCE_ID) + return; + if(!available) + return; + + std::shared_ptr runtime = vsomeip_v3::runtime::get(); + + std::shared_ptr payload = runtime->create_payload(); + constexpr vsomeip_v3::byte_t str[]{"hello world"}; + payload->set_data(str, sizeof(str)); + + std::shared_ptr request = runtime->create_request(); + request->set_service(config::SERVICE_ID); + request->set_instance(config::INSTANCE_ID); + request->set_method(config::METHOD_ID); + request->set_payload(payload); + + for(int i = 0; i < 10; i++) + { + std::cout << "sending: " << str << '\n'; + this->application->send(request); + this->counter_method_request++; + + using namespace std::chrono_literals; + std::this_thread::sleep_for(1s); + } + } + ); + + this->application->request_event( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENT_ID, + {config::EVENTGROUP_ID}, + vsomeip_v3::event_type_e::ET_FIELD, + vsomeip_v3::reliability_type_e::RT_UNRELIABLE + ); + + this->application->subscribe( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENTGROUP_ID + ); +} + +client::~client() +{ + this->application->unsubscribe( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENTGROUP_ID + ); + + this->application->release_event( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENT_ID + ); + + this->application->release_service( + config::SERVICE_ID, + config::INSTANCE_ID + ); +} + +std::size_t client::get_event_count() noexcept +{ + return this->counter_event_received; +} + +std::size_t client::get_method_request_count() noexcept +{ + return this->counter_method_request; +} + +std::size_t client::get_method_response_count() noexcept +{ + return this->counter_method_response; +} + +void client::on_state_registered() +{ + this->application->request_service( + config::SERVICE_ID, + config::INSTANCE_ID + ); +} + +void client::on_state_deregistered() +{ + std::cout << "Client is deregistered!!! Probably could not be registered!!!\n"; +} diff --git a/test/internal_routing_disabled_acceptance_test/client.hpp b/test/internal_routing_disabled_acceptance_test/client.hpp new file mode 100644 index 0000000..f6eba65 --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/client.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "applet.hpp" + +struct client final : applet +{ + client(); + ~client(); + + std::size_t get_event_count() noexcept; + std::size_t get_method_request_count() noexcept; + std::size_t get_method_response_count() noexcept; + +private: + void on_state_registered() override; + void on_state_deregistered() override; + + std::atomic_size_t counter_event_received; + std::atomic_size_t counter_method_request; + std::atomic_size_t counter_method_response; +}; diff --git a/test/internal_routing_disabled_acceptance_test/config.hpp b/test/internal_routing_disabled_acceptance_test/config.hpp new file mode 100644 index 0000000..50dab14 --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/config.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include + +namespace config +{ + constexpr vsomeip_v3::service_t SERVICE_ID = 0x2222; + constexpr vsomeip_v3::instance_t INSTANCE_ID = 0x3333; + constexpr vsomeip_v3::method_t METHOD_ID = 0x4444; + constexpr vsomeip_v3::event_t EVENT_ID = 0x5555; + constexpr vsomeip_v3::eventgroup_t EVENTGROUP_ID = 0x6666; +} diff --git a/test/internal_routing_disabled_acceptance_test/main.cpp b/test/internal_routing_disabled_acceptance_test/main.cpp new file mode 100644 index 0000000..7a2e7fc --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include + +#include "client.hpp" +#include "server.hpp" + +TEST(internal_routing_disabled_acceptance_test, check_connectivity) +{ + server s; + client c; + + using namespace std::chrono_literals; + std::this_thread::sleep_for(15s); + + std::cout + << "[server]\n" + << "\tevents: " << s.get_event_count() << '\n' + << "\tmethod requests: " << s.get_method_request_count() << '\n' + << "\tmethod responses: " << s.get_method_response_count() << '\n'; + + std::cout + << "[client]\n" + << "\tevents: " << c.get_event_count() << '\n' + << "\tmethod requests: " << c.get_method_request_count() << '\n' + << "\tmethod responses: " << c.get_method_response_count() << '\n'; + + EXPECT_EQ(s.get_event_count(), 10); + EXPECT_EQ(s.get_method_request_count(), 0); + EXPECT_EQ(s.get_method_response_count(), 0); + + EXPECT_EQ(c.get_event_count(), 0); + EXPECT_EQ(c.get_method_request_count(), 0); + EXPECT_EQ(c.get_method_response_count(), 0); +} + +int main(int count, char** values) +{ + testing::InitGoogleTest(&count, values); + return RUN_ALL_TESTS(); +} diff --git a/test/internal_routing_disabled_acceptance_test/server.cpp b/test/internal_routing_disabled_acceptance_test/server.cpp new file mode 100644 index 0000000..6e00b1e --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/server.cpp @@ -0,0 +1,132 @@ +#include "server.hpp" + +#include +#include +#include + +#include +#include +#include +#include + +#include "config.hpp" + +server::server() : applet{"server"}, counter_event_sent{}, counter_method_request{}, counter_method_response{} +{ + this->application->register_message_handler( + config::SERVICE_ID, + config::INSTANCE_ID, + config::METHOD_ID, + [this](const std::shared_ptr& message){ + std::shared_ptr runtime = vsomeip_v3::runtime::get(); + std::shared_ptr payload = message->get_payload(); + + switch(message->get_message_type()) + { + case vsomeip_v3::message_type_e::MT_REQUEST: + std::cout << "GOT REQUEST\n"; + this->counter_method_request++; + { + std::shared_ptr response = runtime->create_response(message); + response->set_payload(payload); + + this->application->send(response); + this->counter_method_response++; + + this->application->notify( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENT_ID, + payload, + true + ); + this->counter_event_sent++; + } + break; + + default: + std::cout << "unhandled message type: " << unsigned(message->get_message_type()) << '\n'; + } + } + ); + + this->application->offer_event( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENT_ID, + {config::EVENTGROUP_ID}, + vsomeip_v3::event_type_e::ET_FIELD, + {}, + false, + true, + nullptr, + vsomeip_v3::reliability_type_e::RT_UNRELIABLE + ); + + std::thread{ + [this]{ + using namespace std::chrono_literals; + std::this_thread::sleep_for(1s); + + std::shared_ptr runtime = vsomeip_v3::runtime::get(); + std::shared_ptr payload = runtime->create_payload(); + for(int i = 0; i < 10; i++) + { + int j = i | 0x30; + payload->set_data(reinterpret_cast(&j), sizeof(j)); + this->application->notify( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENT_ID, + payload, + true + ); + this->counter_event_sent++; + + std::this_thread::sleep_for(1s); + } + } + }.detach(); +} + +server::~server() +{ + this->application->stop_offer_event( + config::SERVICE_ID, + config::INSTANCE_ID, + config::EVENT_ID + ); + + this->application->stop_offer_service( + config::SERVICE_ID, + config::INSTANCE_ID + ); +} + +std::size_t server::get_event_count() noexcept +{ + return this->counter_event_sent; +} + +std::size_t server::get_method_request_count() noexcept +{ + return this->counter_method_request; +} + +std::size_t server::get_method_response_count() noexcept +{ + return this->counter_method_response; +} + +void server::on_state_registered() +{ + this->application->offer_service( + config::SERVICE_ID, + config::INSTANCE_ID + ); +} + +void server::on_state_deregistered() +{ + std::cout << "Server is deregistered!!! Probably could not be registered!!!\n"; +} diff --git a/test/internal_routing_disabled_acceptance_test/server.hpp b/test/internal_routing_disabled_acceptance_test/server.hpp new file mode 100644 index 0000000..53685f3 --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/server.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include + +#include "applet.hpp" + +struct server final : applet +{ + server(); + ~server(); + + std::size_t get_event_count() noexcept; + std::size_t get_method_request_count() noexcept; + std::size_t get_method_response_count() noexcept; + +private: + void on_state_registered() override; + void on_state_deregistered() override; + + std::atomic_size_t counter_event_sent; + std::atomic_size_t counter_method_request; + std::atomic_size_t counter_method_response; +}; diff --git a/test/internal_routing_disabled_acceptance_test/vsomeip.json b/test/internal_routing_disabled_acceptance_test/vsomeip.json new file mode 100644 index 0000000..f8ec145 --- /dev/null +++ b/test/internal_routing_disabled_acceptance_test/vsomeip.json @@ -0,0 +1,35 @@ +{ + "logging": { + "level": "trace", + "console": "true" + }, + "applications": [ + { + "name": "server", + "id": "0x1001" + }, + { + "name": "client", + "id": "0x1002" + } + ], + "services": [ + { + "service": "0x2222", + "instance": "0x3333", + "unreliable": 12345 + } + ], + "routing": { + "enabled": "false", + "host": "server", + "address": "127.0.0.1", + "port": 1270 + }, + "service-discovery": { + "enable": "true", + "multicast": "224.244.224.244", + "port": 2240, + "protocol": "udp" + } +} diff --git a/test/magic_cookies_tests/conf/magic_cookies_test_client.json.in b/test/magic_cookies_tests/conf/magic_cookies_test_client.json.in deleted file mode 100644 index bcb2e29..0000000 --- a/test/magic_cookies_tests/conf/magic_cookies_test_client.json.in +++ /dev/null @@ -1,85 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "netmask":"255.255.255.0", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"true", - "path":"/var/log/vsomeip.log" - }, - "dlt":"true" - }, - "applications": - [ - { - "name":"magic_cookies_test_client", - "id":"0x1343" - } - ], - "services": - [ - { - "service":"0x1234", - "instance":"0x5678", - "unicast":"@TEST_IP_MASTER@", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"true" - }, - "events": - [ - { - "event":"0x0777", - "is_field":"true" - }, - { - "event":"0x0778", - "is_field":"false" - }, - { - "event":"0x0779", - "is_field":"true" - } - ], - "eventgroups": - [ - { - "eventgroup":"0x4455", - "events": - [ - "0x777", - "0x778" - ] - }, - { - "eventgroup":"0x4465", - "events": - [ - "0x778", - "0x779" - ] - }, - { - "eventgroup":"0x4555", - "events": - [ - "0x777", - "0x779" - ] - } - ] - } - ], - "routing":"magic_cookies_test_client", - "service-discovery": - { - "enable":"false", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/magic_cookies_tests/conf/magic_cookies_test_service.json.in b/test/magic_cookies_tests/conf/magic_cookies_test_service.json.in deleted file mode 100644 index 0e53c24..0000000 --- a/test/magic_cookies_tests/conf/magic_cookies_test_service.json.in +++ /dev/null @@ -1,88 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"debug", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"magic_cookies_test_service", - "id":"0x1277" - } - ], - "services": - [ - { - "service":"0x1234", - "instance":"0x5678", - "reliable": - { - "port":"30509", - "enable-magic-cookies":"true" - }, - "events": - [ - { - "event":"0x0777", - "is_field":"false", - "is_reliable":"true", - "update-cycle":"2000" - }, - { - "event":"0x0778", - "is_field":"true", - "is_reliable":"true", - "update-cycle":"0" - }, - { - "event":"0x0779", - "is_field":"false", - "is_reliable":"true" - } - ], - "eventgroups": - [ - { - "eventgroup":"0x4455", - "events": - [ - "0x777", - "0x778" - ] - }, - { - "eventgroup":"0x4465", - "events": - [ - "0x778", - "0x779" - ] - }, - { - "eventgroup":"0x4555", - "events": - [ - "0x777", - "0x779" - ] - } - ] - } - ], - "routing":"magic_cookies_test_service", - "service-discovery": - { - "enable":"false", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/magic_cookies_tests/magic_cookies_test_client.cpp b/test/magic_cookies_tests/magic_cookies_test_client.cpp deleted file mode 100644 index dc02309..0000000 --- a/test/magic_cookies_tests/magic_cookies_test_client.cpp +++ /dev/null @@ -1,246 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include - -#include - -#include - -#include "../someip_test_globals.hpp" -#include "../implementation/runtime/include/application_impl.hpp" -#include "../implementation/routing/include/routing_manager.hpp" - -class magic_cookies_test_client { -public: - magic_cookies_test_client() - : app_(new vsomeip::application_impl("")), - is_blocked_(false), - sent_messages_good_(8), - sent_messages_bad_(7), - received_responses_(0), - received_errors_(0), - wait_for_replies_(true), - runner_(std::bind(&magic_cookies_test_client::run, this)) { - } - - void init() { - VSOMEIP_INFO << "Initializing..."; - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - exit(EXIT_FAILURE); - } - - app_->register_state_handler( - std::bind( - &magic_cookies_test_client::on_state, - this, - std::placeholders::_1)); - - app_->register_message_handler( - vsomeip::ANY_SERVICE, vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, - std::bind(&magic_cookies_test_client::on_message, - this, - std::placeholders::_1)); - - app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - std::bind(&magic_cookies_test_client::on_availability, - this, - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), - vsomeip::DEFAULT_MAJOR, vsomeip::DEFAULT_MINOR); - } - - void start() { - VSOMEIP_INFO << "Starting..."; - app_->start(); - } - - void stop() { - VSOMEIP_INFO << "Stopping..."; - app_->clear_all_handler(); - app_->stop(); - } - - void on_state(vsomeip::state_type_e _state) { - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - VSOMEIP_INFO << "Client registration done."; - app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - vsomeip::ANY_MAJOR, vsomeip::ANY_MINOR); - } - } - - void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) { - VSOMEIP_INFO << "Service [" - << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance - << "] is " - << (_is_available ? "available." : "NOT available."); - - if (vsomeip_test::TEST_SERVICE_SERVICE_ID == _service && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) { - static bool is_available = false; - if (is_available && !_is_available) is_available = false; - else if (_is_available && !is_available) { - is_available = true; - std::lock_guard< std::mutex > its_lock(mutex_); - is_blocked_ = true; - condition_.notify_one(); - } - } - } - - void on_message(const std::shared_ptr< vsomeip::message > &_response) { - if (_response->get_return_code() == vsomeip::return_code_e::E_OK) { - VSOMEIP_INFO << "Received a response from Service [" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() - << "." - << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() - << "] to Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() - << "/" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() - << "]"; - received_responses_++; - } else if (_response->get_return_code() == vsomeip::return_code_e::E_MALFORMED_MESSAGE) { - VSOMEIP_INFO << "Received an error message from Service [" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() - << "." - << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() - << "] to Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() - << "/" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() - << "]"; - received_errors_++; - } - if (received_errors_ == sent_messages_bad_ - && received_responses_ == sent_messages_good_) { - std::lock_guard its_lock(mutex_); - wait_for_replies_ = false; - condition_.notify_one(); - } - } - - void join() { - runner_.join(); - } - - void run() { - std::unique_lock< std::mutex > its_lock(mutex_); - while (!is_blocked_) { - if (std::cv_status::timeout == - condition_.wait_for(its_lock, std::chrono::milliseconds(5000))) { - GTEST_NONFATAL_FAILURE_("Service didn't become available within 5s."); - break; - } - } - VSOMEIP_INFO << "Running..."; - - vsomeip::routing_manager *its_routing = app_->get_routing_manager(); - - vsomeip::byte_t its_good_payload_data[] = { - 0x12, 0x34, 0x84, 0x21, - 0x00, 0x00, 0x00, 0x11, - 0x13, 0x43, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, - 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 - }; - - vsomeip::byte_t its_bad_payload_data[] = { - 0x12, 0x34, 0x84, 0x21, - 0x00, 0x00, 0x01, 0x23, - 0x13, 0x43, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, - 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 - }; - - // Test sequence - its_good_payload_data[11] = 0x01; - its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_bad_payload_data[11] = 0x02; - its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_good_payload_data[11] = 0x03; - its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_bad_payload_data[11] = 0x04; - its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_bad_payload_data[11] = 0x05; - its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_good_payload_data[11] = 0x06; - its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_good_payload_data[11] = 0x07; - its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_bad_payload_data[11] = 0x08; - its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_bad_payload_data[11] = 0x09; - its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_bad_payload_data[11] = 0x0A; - its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_good_payload_data[11] = 0x0B; - its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_good_payload_data[11] = 0x0C; - its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_good_payload_data[11] = 0x0D; - its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_bad_payload_data[11] = 0x0E; - its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - std::this_thread::sleep_for(std::chrono::seconds(11)); - its_good_payload_data[11] = 0x0F; - its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); - - while (wait_for_replies_) { - if(std::cv_status::timeout == - condition_.wait_for(its_lock, std::chrono::milliseconds(5000))) { - GTEST_NONFATAL_FAILURE_("Didn't receive all replies/errors in time"); - break; - } - } - EXPECT_EQ(sent_messages_good_, received_responses_); - EXPECT_EQ(sent_messages_bad_, received_errors_); - stop(); - } - -private: - std::shared_ptr< vsomeip::application_impl > app_; - std::mutex mutex_; - std::condition_variable condition_; - bool is_blocked_; - const std::uint32_t sent_messages_good_; - const std::uint32_t sent_messages_bad_; - std::atomic received_responses_; - std::atomic received_errors_; - bool wait_for_replies_; - std::thread runner_; -}; - -TEST(someip_magic_cookies_test, send_good_and_bad_messages) -{ - magic_cookies_test_client its_client; - its_client.init(); - its_client.start(); - its_client.join(); -} - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} - - diff --git a/test/magic_cookies_tests/magic_cookies_test_client_start.sh b/test/magic_cookies_tests/magic_cookies_test_client_start.sh deleted file mode 100755 index 45f4d3c..0000000 --- a/test/magic_cookies_tests/magic_cookies_test_client_start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=magic_cookies_test_client -export VSOMEIP_CONFIGURATION=magic_cookies_test_client.json -./magic_cookies_test_client diff --git a/test/magic_cookies_tests/magic_cookies_test_service.cpp b/test/magic_cookies_tests/magic_cookies_test_service.cpp deleted file mode 100644 index d8ac4d7..0000000 --- a/test/magic_cookies_tests/magic_cookies_test_service.cpp +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "../someip_test_globals.hpp" - -class magic_cookies_test_service { -public: - magic_cookies_test_service(bool _use_static_routing) : - app_(vsomeip::runtime::get()->create_application()), - is_registered_(false), - use_static_routing_(_use_static_routing), - blocked_(false), - offer_thread_(std::bind(&magic_cookies_test_service::run, this)) { - } - - ~magic_cookies_test_service() { - offer_thread_.join(); - } - void init() { - std::lock_guard its_lock(mutex_); - - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - exit(EXIT_FAILURE); - } - app_->register_message_handler( - vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - vsomeip_test::TEST_SERVICE_METHOD_ID, - std::bind(&magic_cookies_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&magic_cookies_test_service::on_state, this, - std::placeholders::_1)); - - VSOMEIP_INFO<< "Static routing " << (use_static_routing_ ? "ON" : "OFF"); - } - - void start() { - app_->start(); - } - - void offer() { - app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); - } - - void stop_offer() { - app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - if (!is_registered_) { - is_registered_ = true; - std::lock_guard its_lock(mutex_); - blocked_ = true; - condition_.notify_one(); - } - } else { - is_registered_ = false; - } - } - - void on_message(const std::shared_ptr &_request) { - VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _request->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _request->get_session() << "]"; - - std::shared_ptr its_response = vsomeip::runtime::get() - ->create_response(_request); - - std::shared_ptr its_payload = vsomeip::runtime::get() - ->create_payload(); - std::vector its_payload_data; - for (std::size_t i = 0; i < 120; ++i) - its_payload_data.push_back(static_cast(i % 256)); - its_payload->set_data(its_payload_data); - its_response->set_payload(its_payload); - - app_->send(its_response); - if(_request->get_session() == 0x0F) { - std::lock_guard its_lock(mutex_); - blocked_ = true; - condition_.notify_one(); - } - } - - void run() { - std::unique_lock its_lock(mutex_); - while (!blocked_) - condition_.wait(its_lock); - - bool is_offer(true); - blocked_ = false; - - if (use_static_routing_) { - offer(); - while (!blocked_) { - if(std::cv_status::timeout == - condition_.wait_for(its_lock, std::chrono::seconds(200))) { - GTEST_NONFATAL_FAILURE_("Didn't receive all requests within time"); - break; - } - } - std::this_thread::sleep_for(std::chrono::milliseconds(5)); - app_->clear_all_handler(); - app_->stop(); - } else { - while (true) { - if (is_offer) - offer(); - else - stop_offer(); - std::this_thread::sleep_for(std::chrono::milliseconds(10000)); - is_offer = !is_offer; - } - } - } - -private: - std::shared_ptr app_; - bool is_registered_; - bool use_static_routing_; - - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - std::thread offer_thread_; -}; - -static bool use_static_routing = false; - -TEST(someip_magic_cookies_test, reply_to_good_messages) -{ - magic_cookies_test_service its_sample(use_static_routing); - its_sample.init(); - its_sample.start(); -} - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - std::string static_routing_enable("--static-routing"); - for (int i = 1; i < argc; i++) { - if (static_routing_enable == argv[i]) { - use_static_routing = true; - } - } - return RUN_ALL_TESTS(); -} diff --git a/test/magic_cookies_tests/magic_cookies_test_service_start.sh b/test/magic_cookies_tests/magic_cookies_test_service_start.sh deleted file mode 100755 index 9288b7e..0000000 --- a/test/magic_cookies_tests/magic_cookies_test_service_start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=magic_cookies_test_service -export VSOMEIP_CONFIGURATION=magic_cookies_test_service.json -./magic_cookies_test_service --tcp --static-routing diff --git a/test/magic_cookies_tests/magic_cookies_test_starter.sh b/test/magic_cookies_tests/magic_cookies_test_starter.sh deleted file mode 100755 index d05a371..0000000 --- a/test/magic_cookies_tests/magic_cookies_test_starter.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit successfully. - -# Display a message to show the user that he must now call the external service -# to finish the test successfully - -FAIL=0 - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting magic cookies test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./magic_cookies_test_client_start.sh\"" & -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./magic_cookies_test_client_start.sh" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./magic_cookies_test_client_start.sh\" >> $WS_ROOT/slave_test_output 2>&1" & - -else -cat <> $WS_ROOT/slave_test_output 2>&1" & -else -cat < -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include "../../implementation/utility/include/byteorder.hpp" -#include "../../implementation/message/include/deserializer.hpp" -#include "../../implementation/service_discovery/include/service_discovery.hpp" -#include "../../implementation/service_discovery/include/message_impl.hpp" -#include "../../implementation/service_discovery/include/constants.hpp" -#include "../../implementation/service_discovery/include/enumeration_types.hpp" -#include "../../implementation/service_discovery/include/eventgroupentry_impl.hpp" -#include "../../implementation/service_discovery/include/serviceentry_impl.hpp" -#include "../../implementation/message/include/message_impl.hpp" -#include "../../implementation/service_discovery/include/option_impl.hpp" -#include "../../implementation/service_discovery/include/ipv4_option_impl.hpp" -#include "malicious_data_test_globals.hpp" - -static char* remote_address; -static char* local_address; - -class malicious_data : public ::testing::Test { -public: - malicious_data() : - work_(std::make_shared(io_)), - io_thread_(std::bind(&malicious_data::io_run, this)) {} -protected: - - void TearDown() { - work_.reset(); - io_thread_.join(); - io_.stop(); - } - - void io_run() { - io_.run(); - } - - boost::asio::io_service io_; - std::shared_ptr work_; - std::thread io_thread_; -}; - -TEST_F(malicious_data, send_malicious_events) -{ - std::promise client_subscribed; - - boost::asio::ip::tcp::socket tcp_socket(io_); - boost::asio::ip::udp::socket udp_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - - std::thread receive_thread([&](){ - std::atomic keep_receiving(true); - std::function receive; - std::vector receive_buffer(4096); - std::vector its_received_events; - - const std::function receive_cbk = [&]( - const boost::system::error_code& error, std::size_t bytes_transferred) { - if (error) { - keep_receiving = false; - ADD_FAILURE() << __func__ << " error: " << error.message(); - return; - } - #if 0 - std::stringstream str; - for (size_t i = 0; i < bytes_transferred; i++) { - str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; - } - std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; - #endif - - vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], - receive_buffer[VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], - receive_buffer[VSOMEIP_METHOD_POS_MAX]); - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_EQ(1u, sd_msg.get_entries().size()); - for (const auto& e : sd_msg.get_entries()) { - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { - EXPECT_TRUE(e->is_eventgroup_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); - EXPECT_EQ(1,e->get_num_options(1)); - EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); - EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); - EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); - EXPECT_EQ(1u, sd_msg.get_options().size()); - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); - } - client_subscribed.set_value(true); - keep_receiving = false; - } - } - } - - - }; - - receive = [&]() { - udp_socket.async_receive(boost::asio::buffer(receive_buffer, receive_buffer.capacity()), - receive_cbk); - }; - - receive(); - while(keep_receiving) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - }); - - std::thread send_thread([&]() { - try { - std::promise client_connected; - boost::asio::ip::tcp::socket::endpoint_type local( - boost::asio::ip::address::from_string(std::string(local_address)), - 40001); - boost::asio::ip::tcp::acceptor its_acceptor(io_); - boost::system::error_code ec; - its_acceptor.open(local.protocol(), ec); - boost::asio::detail::throw_error(ec, "acceptor open"); - its_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "acceptor set_option"); - its_acceptor.bind(local, ec); - boost::asio::detail::throw_error(ec, "acceptor bind"); - its_acceptor.listen(boost::asio::socket_base::max_connections, ec); - boost::asio::detail::throw_error(ec, "acceptor listen"); - its_acceptor.async_accept(tcp_socket, [&](boost::system::error_code _error) { - if (!_error) { - // Nagle algorithm off - tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); - client_connected.set_value(true); - } else { - ADD_FAILURE() << "accept_cbk: " << _error.message(); - } - }); - - - // offer the service - std::uint8_t its_offer_service_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x30, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, // length entries array - 0x01, 0x00, 0x00, 0x20, - 0x33, 0x44, 0x00, 0x01, // service / instance - 0x00, 0xff, 0xff, 0xff, // major / ttl - 0x00, 0x00, 0x00, 0x00, // minor - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // slave address - 0x00, 0x06, 0x9c, 0x41, - }; - boost::asio::ip::address its_local_address = - boost::asio::ip::address::from_string(std::string(local_address)); - std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); - - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30490); - udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); - - // wait until client established TCP connection - if (std::future_status::timeout == client_connected.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Client didn't connect within time"; - } - - // wait until client subscribed - if (std::future_status::timeout == client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Client didn't subscribe within time"; - } - - // send malicious data as server - std::uint8_t its_malicious_data[] = { - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x11, 0x3f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x38, 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x5f, 0x5f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x86, 0x6f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xad, 0x7f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xd4, 0x8f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xfb, 0x9f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x22, 0xaf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, // payload missing - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0xbf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x70, 0xcf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x43, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x6d, 0x80, 0x00, 0x45, 0x22, 0x80, 0x00, 0x45, 0x3b, 0x80, 0x00, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x97, 0xdf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x23, 0x99, 0x00, 0x4e, 0xb3, 0xe4, 0x4e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x48, 0x00, 0x00, 0x45, 0x96, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x45, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x22, 0x91, 0x00, 0x4e, 0xb3, 0xe3, 0xd7, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x44, 0x48, 0x00, 0x00, 0x45, 0x9c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xe5, 0xff, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x21, 0x6c, 0x00, 0x4e, 0xb3, 0xe3, 0x55, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x20, 0x00, 0x44, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0d, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x20, 0xa9, 0x00, 0x4e, 0xb3, 0xe3, 0x56, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x45, 0x6d, 0x80, 0x00, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x34, 0x1f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1f, 0xc6, 0x00, 0x4e, 0xb3, 0xe3, 0x87, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x96, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x44, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x5b, 0x2f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1e, 0xf1, 0x00, 0x4e, 0xb3, 0xe3, 0x5e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x45, 0x9c, 0x40, 0x00, 0x45, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x82, 0x3f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xad, 0x00, 0x4e, 0xb3, 0xe3, 0xa8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x48, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x44, 0xaf, 0x00, 0x00, 0x45, 0x3b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xa9, 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xec, 0x00, 0x4e, 0xb3, 0xe3, 0xd8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa8, 0xc0, 0x00, 0x44, 0xaf, 0x00, 0x00, 0x45, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xd0, 0x5f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfa, 0x00, 0x00, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xf7, 0x6f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x19, 0x20, 0x00, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1e, 0x7f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x09, 0x80, 0x00, 0x44, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - tcp_socket.send(boost::asio::buffer(its_malicious_data)); - - // establish second tcp connection as client and send malicious data as well - boost::asio::ip::tcp::socket tcp_socket2(io_); - boost::asio::ip::tcp::socket::endpoint_type remote( - boost::asio::ip::address::from_string(std::string(remote_address)), - 40001); - tcp_socket2.open(remote.protocol()); - tcp_socket2.connect(remote); - std::uint8_t its_malicious_client_data[] = { - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x11, 0x3f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x38, 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x5f, 0x5f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x86, 0x6f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xad, 0x7f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xd4, 0x8f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xfb, 0x9f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x22, 0xaf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, // payload missing - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0xbf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x70, 0xcf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x43, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x6d, 0x80, 0x00, 0x45, 0x22, 0x80, 0x00, 0x45, 0x3b, 0x80, 0x00, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x97, 0xdf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x23, 0x99, 0x00, 0x4e, 0xb3, 0xe4, 0x4e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x48, 0x00, 0x00, 0x45, 0x96, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x45, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x22, 0x91, 0x00, 0x4e, 0xb3, 0xe3, 0xd7, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x44, 0x48, 0x00, 0x00, 0x45, 0x9c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xe5, 0xff, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x21, 0x6c, 0x00, 0x4e, 0xb3, 0xe3, 0x55, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x20, 0x00, 0x44, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0d, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x20, 0xa9, 0x00, 0x4e, 0xb3, 0xe3, 0x56, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x45, 0x6d, 0x80, 0x00, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x34, 0x1f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1f, 0xc6, 0x00, 0x4e, 0xb3, 0xe3, 0x87, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x96, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x44, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x5b, 0x2f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1e, 0xf1, 0x00, 0x4e, 0xb3, 0xe3, 0x5e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x45, 0x9c, 0x40, 0x00, 0x45, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x82, 0x3f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xad, 0x00, 0x4e, 0xb3, 0xe3, 0xa8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x48, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x44, 0xaf, 0x00, 0x00, 0x45, 0x3b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xa9, 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xec, 0x00, 0x4e, 0xb3, 0xe3, 0xd8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa8, 0xc0, 0x00, 0x44, 0xaf, 0x00, 0x00, 0x45, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xd0, 0x5f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfa, 0x00, 0x00, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xf7, 0x6f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x19, 0x20, 0x00, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1e, 0x7f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x09, 0x80, 0x00, 0x44, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - tcp_socket2.send(boost::asio::buffer(its_malicious_client_data)); - - std::this_thread::sleep_for(std::chrono::milliseconds(1500)); - // call shutdown method - std::uint8_t shutdown_call[] = { - 0x33, 0x45, 0x14, 0x04, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); - } catch (const std::exception& _e) { - ADD_FAILURE() << "catched exception: " << _e.what(); - } - - }); - - send_thread.join(); - receive_thread.join(); - boost::system::error_code ec; - udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket.close(ec); - tcp_socket.close(ec); - -} - -/* - * @test Send a message with an invalid protocol version to the test master - * two times as client and two time as service. Ensure that message with the - * WRONG_PROTOCOL_VERSION is sent back in both cases and that the client - * reestablishes the TCP connection after the service sent an message with an - * invalid protocol version back - */ -TEST_F(malicious_data, send_wrong_protocol_version) -{ - std::promise remote_client_subscribed; - std::promise offer_received; - - boost::asio::ip::tcp::socket tcp_socket(io_); - boost::asio::ip::udp::socket udp_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - - std::thread sd_receive_thread([&](){ - std::atomic keep_receiving(true); - std::vector receive_buffer(4096); - std::vector its_received_events; - std::atomic service_offered(false); - std::atomic client_subscribed(false); - - // join the sd multicast group 224.0.24.1 - udp_socket.set_option(boost::asio::ip::multicast::join_group( - boost::asio::ip::address::from_string("224.0.24.1").to_v4())); - - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = udp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - ADD_FAILURE() << __func__ << " error: " << error.message(); - return; - } else { - vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], - receive_buffer[VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], - receive_buffer[VSOMEIP_METHOD_POS_MAX]); - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_EQ(1u, sd_msg.get_entries().size()); - for (const auto& e : sd_msg.get_entries()) { - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { - EXPECT_TRUE(e->is_eventgroup_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); - EXPECT_EQ(1,e->get_num_options(1)); - EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); - EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); - EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); - EXPECT_EQ(1u, sd_msg.get_options().size()); - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); - } - remote_client_subscribed.set_value(); - client_subscribed = true; - } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { - EXPECT_TRUE(e->is_service_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); - EXPECT_EQ(2,e->get_num_options(1)); - EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); - EXPECT_EQ(malicious_data_test::service.service_id + 1u, e->get_service()); - EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); - EXPECT_EQ(2u, sd_msg.get_options().size()); - if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_EQ(0u, its_casted_entry->get_minor_version()); - } - offer_received.set_value(); - service_offered = true; - } - } - if (service_offered && client_subscribed) { - keep_receiving = false; - } - } else { - ADD_FAILURE() << " received non-sd message"; - } - } - } - }); - - std::thread send_thread([&]() { - try { - std::promise client_connected; - boost::asio::ip::tcp::socket::endpoint_type local( - boost::asio::ip::address::from_string(std::string(local_address)), - 40001); - boost::asio::ip::tcp::acceptor its_acceptor(io_); - boost::system::error_code ec; - its_acceptor.open(local.protocol(), ec); - boost::asio::detail::throw_error(ec, "acceptor open"); - its_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "acceptor set_option"); - its_acceptor.bind(local, ec); - boost::asio::detail::throw_error(ec, "acceptor bind"); - its_acceptor.listen(boost::asio::socket_base::max_connections, ec); - boost::asio::detail::throw_error(ec, "acceptor listen"); - its_acceptor.async_accept(tcp_socket, [&](boost::system::error_code _error) { - if (!_error) { - // Nagle algorithm off - tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); - client_connected.set_value(); - } else { - ADD_FAILURE() << "accept_cbk: " << _error.message(); - } - }); - - - // offer the service - std::uint8_t its_offer_service_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x30, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, // length entries array - 0x01, 0x00, 0x00, 0x20, - 0x33, 0x44, 0x00, 0x01, // service / instance - 0x00, 0xff, 0xff, 0xff, // major / ttl - 0x00, 0x00, 0x00, 0x00, // minor - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // slave address - 0x00, 0x06, 0x9c, 0x41, - }; - boost::asio::ip::address its_local_address = - boost::asio::ip::address::from_string(std::string(local_address)); - std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); - - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30490); - udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); - - // wait until client established TCP connection - if (std::future_status::timeout == client_connected.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Client didn't connect within time"; - } - - // wait until client subscribed - if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Client didn't subscribe within time"; - } - - // wait until a offer was received - if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive offer within time"; - } - - std::atomic fin_as_service_received(0); - std::promise client_reconnected1; - - std::thread tcp_receive_thread([&]() { - std::atomic keep_receiving(true); - std::vector receive_buffer(4096); - - while (keep_receiving) { - boost::system::error_code error; - tcp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error == boost::asio::error::eof) { - EXPECT_EQ(boost::asio::error::eof, error); - fin_as_service_received++; - keep_receiving = false; - } else { - keep_receiving = false; - ADD_FAILURE() << __func__ << ":" << __LINE__ << " error: " << error.message(); - return; - } - } - }); - - boost::asio::ip::tcp::socket tcp_socket3(io_); - its_acceptor.async_accept(tcp_socket3, [&](boost::system::error_code _error) { - if (!_error) { - // Nagle algorithm off - tcp_socket3.set_option(boost::asio::ip::tcp::no_delay(true)); - client_reconnected1.set_value(); - } else { - ADD_FAILURE() << "accept_cbk2: " << _error.message(); - } - }); - // send malicious data as server (too long length and wrong protocol version) - std::uint8_t its_malicious_data[] = { - 0x33, 0x45, 0x00, 0x01, - 0x00, 0x00, 0x07, 0x7f, - 0xBB, 0xBB, 0xCA, 0xFE, - 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA - }; - tcp_socket.send(boost::asio::buffer(its_malicious_data)); - - // wait until client reestablished TCP connection - if (std::future_status::timeout == client_reconnected1.get_future().wait_for(std::chrono::seconds(10))) { - tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket3.close(ec); - ADD_FAILURE() << "Client didn't reconnect within time 1"; - } - - tcp_receive_thread.join(); - - EXPECT_EQ(1u, fin_as_service_received); - - std::thread tcp_receive_thread2([&]() { - std::atomic keep_receiving(true); - std::vector receive_buffer(4096); - while (keep_receiving) { - boost::system::error_code error; - tcp_socket3.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error == boost::asio::error::eof) { - EXPECT_EQ(boost::asio::error::eof, error); - fin_as_service_received++; - // client must sent back error response before closing the connection - EXPECT_EQ(2u, fin_as_service_received); - if (fin_as_service_received == 2) { - keep_receiving = false; - } - } else { - keep_receiving = false; - return; - } - } - }); - - // send malicious data as server (wrong protocol version) - std::uint8_t its_malicious_data_correct_length[] = { - 0x33, 0x45, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x08, - 0xBB, 0xBB, 0xCA, 0xFE, - 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA - }; - tcp_socket3.send(boost::asio::buffer(its_malicious_data_correct_length)); - - tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket3.close(ec); - - - tcp_receive_thread2.join(); - EXPECT_EQ(2u, fin_as_service_received); - - // establish second tcp connection as client and send malicious data as well - std::atomic error_response_as_client_received(0); - std::atomic fin_as_client_received(0); - - boost::asio::ip::tcp::socket tcp_socket2(io_); - boost::asio::ip::tcp::socket::endpoint_type remote( - boost::asio::ip::address::from_string(std::string(remote_address)), - 40001); - tcp_socket2.open(remote.protocol()); - tcp_socket2.connect(remote); - - - std::thread tcp_service_receive_thread([&]() { - std::atomic keep_receiving(true); - std::vector receive_buffer(4096); - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = tcp_socket2.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (!error) { - #if 0 - std::stringstream str; - for (size_t i = 0; i < bytes_transferred; i++) { - str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; - } - std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; - #endif - vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - std::shared_ptr its_message(its_deserializer.deserialize_message()); - EXPECT_EQ(0x3345, its_message->get_service()); - EXPECT_EQ(0x1, its_message->get_method()); - EXPECT_EQ(0xCCCC, its_message->get_client()); - EXPECT_EQ(0xDDDD, its_message->get_session()); - EXPECT_EQ(vsomeip::return_code_e::E_WRONG_PROTOCOL_VERSION, its_message->get_return_code()); - EXPECT_EQ(vsomeip::message_type_e::MT_ERROR, its_message->get_message_type()); - error_response_as_client_received++; - // service must sent back error response before closing the connection - EXPECT_EQ(error_response_as_client_received - 1u, fin_as_client_received); - } else { - EXPECT_EQ(boost::asio::error::eof, error); - fin_as_client_received++; - // service must sent back error response before closing the connection - EXPECT_EQ(error_response_as_client_received, fin_as_client_received); - if (fin_as_client_received == 1) { - keep_receiving = false; - } - } - } - }); - - // send malicious data as client (too long length and wrong protocol version) - std::uint8_t its_malicious_client_data[] = { - 0x33, 0x45, 0x00, 0x01, - 0x00, 0x00, 0x07, 0x7f, - 0xCC, 0xCC, 0xDD, 0xDD, - 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA - }; - tcp_socket2.send(boost::asio::buffer(its_malicious_client_data)); - tcp_service_receive_thread.join(); - EXPECT_EQ(1u, error_response_as_client_received); - EXPECT_EQ(1u, fin_as_client_received); - - tcp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket2.close(ec); - - // establish a tcp connection as client again and send wrong protocol - // version in message with a correct length field - boost::asio::ip::tcp::socket tcp_socket5(io_); - tcp_socket5.open(remote.protocol()); - tcp_socket5.connect(remote); - - std::thread tcp_service_receive_thread2([&]() { - std::atomic keep_receiving(true); - std::vector receive_buffer(4096); - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = tcp_socket5.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (!error) { - vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - std::shared_ptr its_message(its_deserializer.deserialize_message()); - EXPECT_EQ(0x3345, its_message->get_service()); - EXPECT_EQ(0x1, its_message->get_method()); - EXPECT_EQ(0xCCCC, its_message->get_client()); - EXPECT_EQ(0xDDDD, its_message->get_session()); - EXPECT_EQ(vsomeip::return_code_e::E_WRONG_PROTOCOL_VERSION, its_message->get_return_code()); - EXPECT_EQ(vsomeip::message_type_e::MT_ERROR, its_message->get_message_type()); - error_response_as_client_received++; - // service must sent back error response before closing the connection - EXPECT_EQ(error_response_as_client_received - 1u, fin_as_client_received); - if (error_response_as_client_received == 2) { - keep_receiving = false; - } - } - } - }); - - // send malicious data as client (wrong protocol version) - std::uint8_t its_malicious_client_data_correct_length[] = { - 0x33, 0x45, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x08, - 0xCC, 0xCC, 0xDD, 0xDD, - 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA - }; - tcp_socket5.send(boost::asio::buffer(its_malicious_client_data_correct_length)); - tcp_service_receive_thread2.join(); - EXPECT_EQ(2u, error_response_as_client_received); - EXPECT_EQ(1u, fin_as_client_received); - - tcp_socket5.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket5.close(ec); - - // call shutdown method - std::uint8_t shutdown_call[] = { - 0x33, 0x45, 0x14, 0x04, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); - udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); - udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket2.close(ec); - } catch (const std::exception& _e) { - ADD_FAILURE() << "catched exception: " << _e.what(); - } - - }); - - send_thread.join(); - sd_receive_thread.join(); - boost::system::error_code ec; - udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket.close(ec); - tcp_socket.close(ec); - -} - -/* - * @test Send a message with an invalid message type to the test master - * one time as client and one time as service. Ensure that the client - * reestablishes the TCP connection after the service sent an message with an - * invalid protocol version back - */ -TEST_F(malicious_data, send_wrong_message_type) -{ - std::promise remote_client_subscribed; - std::promise offer_received; - - boost::asio::ip::tcp::socket tcp_socket(io_); - boost::asio::ip::udp::socket udp_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - - std::thread sd_receive_thread([&](){ - std::atomic keep_receiving(true); - std::vector receive_buffer(4096); - std::vector its_received_events; - std::atomic service_offered(false); - std::atomic client_subscribed(false); - - // join the sd multicast group 224.0.24.1 - udp_socket.set_option(boost::asio::ip::multicast::join_group( - boost::asio::ip::address::from_string("224.0.24.1").to_v4())); - - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = udp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - ADD_FAILURE() << __func__ << " error: " << error.message(); - return; - } else { - vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], - receive_buffer[VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], - receive_buffer[VSOMEIP_METHOD_POS_MAX]); - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_EQ(1u, sd_msg.get_entries().size()); - for (const auto& e : sd_msg.get_entries()) { - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { - EXPECT_TRUE(e->is_eventgroup_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); - EXPECT_EQ(1,e->get_num_options(1)); - EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); - EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); - EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); - EXPECT_EQ(1u, sd_msg.get_options().size()); - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); - } - remote_client_subscribed.set_value(); - client_subscribed = true; - } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { - EXPECT_TRUE(e->is_service_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); - EXPECT_EQ(2,e->get_num_options(1)); - EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); - EXPECT_EQ(malicious_data_test::service.service_id + 1u, e->get_service()); - EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); - EXPECT_EQ(2u, sd_msg.get_options().size()); - if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_EQ(0u, its_casted_entry->get_minor_version()); - } - offer_received.set_value(); - service_offered = true; - } - } - if (service_offered && client_subscribed) { - keep_receiving = false; - } - } else { - ADD_FAILURE() << " received non-sd message"; - } - } - } - }); - - std::thread send_thread([&]() { - try { - std::promise client_connected; - boost::asio::ip::tcp::socket::endpoint_type local( - boost::asio::ip::address::from_string(std::string(local_address)), - 40001); - boost::asio::ip::tcp::acceptor its_acceptor(io_); - boost::system::error_code ec; - its_acceptor.open(local.protocol(), ec); - boost::asio::detail::throw_error(ec, "acceptor open"); - its_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "acceptor set_option"); - its_acceptor.bind(local, ec); - boost::asio::detail::throw_error(ec, "acceptor bind"); - its_acceptor.listen(boost::asio::socket_base::max_connections, ec); - boost::asio::detail::throw_error(ec, "acceptor listen"); - its_acceptor.async_accept(tcp_socket, [&](boost::system::error_code _error) { - if (!_error) { - // Nagle algorithm off - tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); - client_connected.set_value(); - } else { - ADD_FAILURE() << "accept_cbk: " << _error.message(); - } - }); - - - // offer the service - std::uint8_t its_offer_service_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x30, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, // length entries array - 0x01, 0x00, 0x00, 0x20, - 0x33, 0x44, 0x00, 0x01, // service / instance - 0x00, 0xff, 0xff, 0xff, // major / ttl - 0x00, 0x00, 0x00, 0x00, // minor - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // slave address - 0x00, 0x06, 0x9c, 0x41, - }; - boost::asio::ip::address its_local_address = - boost::asio::ip::address::from_string(std::string(local_address)); - std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); - - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30490); - udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); - - // wait until client established TCP connection - if (std::future_status::timeout == client_connected.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Client didn't connect within time"; - } - - // wait until client subscribed - if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Client didn't subscribe within time"; - } - - // wait until a offer was received - if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive offer within time"; - } - - std::atomic fin_as_service_received(false); - std::promise client_reconnected; - - std::thread tcp_receive_thread([&]() { - std::atomic keep_receiving(true); - std::vector receive_buffer(4096); - - while (keep_receiving) { - boost::system::error_code error; - tcp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (!error) { - ADD_FAILURE() << __func__ << ":" << __LINE__ - << " received a non-error:" << error.message(); - } else if (error == boost::asio::error::eof) { - EXPECT_EQ(boost::asio::error::eof, error); - fin_as_service_received = true; - keep_receiving = false; - } else { - keep_receiving = false; - ADD_FAILURE() << __func__ << ":" << __LINE__ << " error: " << error.message(); - return; - } - } - }); - - boost::asio::ip::tcp::socket tcp_socket3(io_); - its_acceptor.async_accept(tcp_socket3, [&](boost::system::error_code _error) { - if (!_error) { - // Nagle algorithm off - tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); - client_reconnected.set_value(); - } else { - ADD_FAILURE() << "accept_cbk2: " << _error.message(); - } - }); - // send malicious data as server (too long length and wrong message type) - std::uint8_t its_malicious_data[] = { - 0x33, 0x45, 0x00, 0x01, - 0x00, 0x00, 0x07, 0x7f, - 0xBB, 0xBB, 0xCA, 0xFE, - 0x01, 0x00, 0xAA, 0x00 // message type set to 0xAA - }; - tcp_socket.send(boost::asio::buffer(its_malicious_data)); - - // wait until client reestablished TCP connection - if (std::future_status::timeout == client_reconnected.get_future().wait_for(std::chrono::seconds(10))) { - tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket3.close(ec); - ADD_FAILURE() << "Client didn't reconnect within time"; - } else { - tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket3.close(ec); - } - - tcp_receive_thread.join(); - - EXPECT_TRUE(fin_as_service_received); - - - // establish second tcp connection as client and send malicious data as well - std::atomic fin_as_client_received(false); - - boost::asio::ip::tcp::socket tcp_socket2(io_); - boost::asio::ip::tcp::socket::endpoint_type remote( - boost::asio::ip::address::from_string(std::string(remote_address)), - 40001); - tcp_socket2.open(remote.protocol()); - tcp_socket2.connect(remote); - - - std::thread tcp_service_receive_thread([&]() { - std::atomic keep_receiving(true); - std::function receive; - std::vector receive_buffer(4096); - - auto receive_cbk = [&](const boost::system::error_code& _error, - std::size_t bytes_transferred) { - (void)bytes_transferred; - if (!_error) { - ADD_FAILURE() << __func__ << ":" << __LINE__ - << " received a non-error:" << _error.message(); - } else { - EXPECT_EQ(boost::asio::error::eof, _error); - fin_as_client_received = true; - keep_receiving = false; - - } - }; - - receive = [&]() { - tcp_socket2.async_receive(boost::asio::buffer(receive_buffer, receive_buffer.capacity()), - receive_cbk); - }; - - while (keep_receiving) { - receive(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - }); - - // send malicious data as client (too long length and wrong message type) - std::uint8_t its_malicious_client_data[] = { - 0x33, 0x45, 0x00, 0x01, - 0x00, 0x00, 0x07, 0x7f, - 0xCC, 0xCC, 0xDD, 0xDD, - 0x01, 0x00, 0xAA, 0x00 // protocol version set to 0xAA - }; - tcp_socket2.send(boost::asio::buffer(its_malicious_client_data)); - tcp_service_receive_thread.join(); - EXPECT_TRUE(fin_as_client_received); - - tcp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket2.close(ec); - - // call shutdown method - std::uint8_t shutdown_call[] = { - 0x33, 0x45, 0x14, 0x04, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); - udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); - udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket2.close(ec); - } catch (const std::exception& _e) { - ADD_FAILURE() << "catched exception: " << _e.what(); - } - - }); - - send_thread.join(); - sd_receive_thread.join(); - boost::system::error_code ec; - udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket.close(ec); - tcp_socket.close(ec); - -} - -/* - * @test Send a message with an invalid return code to the test master - * one time as client and one time as service. Ensure that the client - * reestablishes the TCP connection after the service sent an message with an - * invalid protocol version back - */ -TEST_F(malicious_data, send_wrong_return_code) -{ - std::promise remote_client_subscribed; - std::promise offer_received; - - boost::asio::ip::tcp::socket tcp_socket(io_); - boost::asio::ip::udp::socket udp_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - - std::thread sd_receive_thread([&](){ - std::atomic keep_receiving(true); - std::vector receive_buffer(4096); - std::vector its_received_events; - std::atomic service_offered(false); - std::atomic client_subscribed(false); - - // join the sd multicast group 224.0.24.1 - udp_socket.set_option(boost::asio::ip::multicast::join_group( - boost::asio::ip::address::from_string("224.0.24.1").to_v4())); - - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = udp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - ADD_FAILURE() << __func__ << " error: " << error.message(); - return; - } else { - vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], - receive_buffer[VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], - receive_buffer[VSOMEIP_METHOD_POS_MAX]); - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_EQ(1u, sd_msg.get_entries().size()); - for (const auto& e : sd_msg.get_entries()) { - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { - EXPECT_TRUE(e->is_eventgroup_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); - EXPECT_EQ(1,e->get_num_options(1)); - EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); - EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); - EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); - EXPECT_EQ(1u, sd_msg.get_options().size()); - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); - } - remote_client_subscribed.set_value(); - client_subscribed = true; - } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { - EXPECT_TRUE(e->is_service_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); - EXPECT_EQ(2,e->get_num_options(1)); - EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); - EXPECT_EQ(malicious_data_test::service.service_id + 1u, e->get_service()); - EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); - EXPECT_EQ(2u, sd_msg.get_options().size()); - if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_EQ(0u, its_casted_entry->get_minor_version()); - } - offer_received.set_value(); - service_offered = true; - } - } - if (service_offered && client_subscribed) { - keep_receiving = false; - } - } else { - ADD_FAILURE() << " received non-sd message"; - } - } - } - }); - - std::thread send_thread([&]() { - try { - std::promise client_connected; - boost::asio::ip::tcp::socket::endpoint_type local( - boost::asio::ip::address::from_string(std::string(local_address)), - 40001); - boost::asio::ip::tcp::acceptor its_acceptor(io_); - boost::system::error_code ec; - its_acceptor.open(local.protocol(), ec); - boost::asio::detail::throw_error(ec, "acceptor open"); - its_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "acceptor set_option"); - its_acceptor.bind(local, ec); - boost::asio::detail::throw_error(ec, "acceptor bind"); - its_acceptor.listen(boost::asio::socket_base::max_connections, ec); - boost::asio::detail::throw_error(ec, "acceptor listen"); - its_acceptor.async_accept(tcp_socket, [&](boost::system::error_code _error) { - if (!_error) { - // Nagle algorithm off - tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); - client_connected.set_value(); - } else { - ADD_FAILURE() << "accept_cbk: " << _error.message(); - } - }); - - - // offer the service - std::uint8_t its_offer_service_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x30, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, // length entries array - 0x01, 0x00, 0x00, 0x20, - 0x33, 0x44, 0x00, 0x01, // service / instance - 0x00, 0xff, 0xff, 0xff, // major / ttl - 0x00, 0x00, 0x00, 0x00, // minor - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // slave address - 0x00, 0x06, 0x9c, 0x41, - }; - boost::asio::ip::address its_local_address = - boost::asio::ip::address::from_string(std::string(local_address)); - std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); - - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30490); - udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); - - // wait until client established TCP connection - if (std::future_status::timeout == client_connected.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Client didn't connect within time"; - } - - // wait until client subscribed - if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Client didn't subscribe within time"; - } - - // wait until a offer was received - if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive offer within time"; - } - - std::atomic fin_as_service_received(false); - std::promise client_reconnected; - - std::thread tcp_receive_thread([&]() { - std::atomic keep_receiving(true); - std::vector receive_buffer(4096); - - while (keep_receiving) { - boost::system::error_code error; - tcp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (!error) { - ADD_FAILURE() << __func__ << ":" << __LINE__ - << " received a non-error:" << error.message(); - } else if (error == boost::asio::error::eof) { - EXPECT_EQ(boost::asio::error::eof, error); - fin_as_service_received = true; - keep_receiving = false; - } else { - keep_receiving = false; - ADD_FAILURE() << __func__ << ":" << __LINE__ << " error: " << error.message(); - return; - } - } - }); - - boost::asio::ip::tcp::socket tcp_socket3(io_); - its_acceptor.async_accept(tcp_socket3, [&](boost::system::error_code _error) { - if (!_error) { - // Nagle algorithm off - tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); - client_reconnected.set_value(); - } else { - ADD_FAILURE() << "accept_cbk2: " << _error.message(); - } - }); - // send malicious data as server (too long length and wrong return code) - std::uint8_t its_malicious_data[] = { - 0x33, 0x45, 0x00, 0x01, - 0x00, 0x00, 0x07, 0x7f, - 0xBB, 0xBB, 0xCA, 0xFE, - 0x01, 0x00, 0x00, 0xAA // return code set to 0xAA - }; - tcp_socket.send(boost::asio::buffer(its_malicious_data)); - - // wait until client reestablished TCP connection - if (std::future_status::timeout == client_reconnected.get_future().wait_for(std::chrono::seconds(10))) { - tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket3.close(ec); - ADD_FAILURE() << "Client didn't reconnect within time"; - } else { - tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket3.close(ec); - } - - tcp_receive_thread.join(); - - EXPECT_TRUE(fin_as_service_received); - - - // establish second tcp connection as client and send malicious data as well - std::atomic fin_as_client_received(false); - - boost::asio::ip::tcp::socket tcp_socket2(io_); - boost::asio::ip::tcp::socket::endpoint_type remote( - boost::asio::ip::address::from_string(std::string(remote_address)), - 40001); - tcp_socket2.open(remote.protocol()); - tcp_socket2.connect(remote); - - - std::thread tcp_service_receive_thread([&]() { - std::atomic keep_receiving(true); - std::function receive; - std::vector receive_buffer(4096); - - auto receive_cbk = [&](const boost::system::error_code& _error, - std::size_t bytes_transferred) { - (void)bytes_transferred; - if (!_error) { - ADD_FAILURE() << __func__ << ":" << __LINE__ - << " received a non-error:" << _error.message(); - } else { - EXPECT_EQ(boost::asio::error::eof, _error); - fin_as_client_received = true; - keep_receiving = false; - - } - }; - - receive = [&]() { - tcp_socket2.async_receive(boost::asio::buffer(receive_buffer, receive_buffer.capacity()), - receive_cbk); - }; - - while (keep_receiving) { - receive(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - }); - - // send malicious data as client (too long length and wrong return code) - std::uint8_t its_malicious_client_data[] = { - 0x33, 0x45, 0x00, 0x01, - 0x00, 0x00, 0x07, 0x7f, - 0xCC, 0xCC, 0xDD, 0xDD, - 0x01, 0x00, 0x00, 0xAA // return version set to 0xAA - }; - tcp_socket2.send(boost::asio::buffer(its_malicious_client_data)); - tcp_service_receive_thread.join(); - EXPECT_TRUE(fin_as_client_received); - - tcp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket2.close(ec); - - // call shutdown method - std::uint8_t shutdown_call[] = { - 0x33, 0x45, 0x14, 0x04, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); - udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); - udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket2.close(ec); - } catch (const std::exception& _e) { - ADD_FAILURE() << "catched exception: " << _e.what(); - } - - }); - - send_thread.join(); - sd_receive_thread.join(); - boost::system::error_code ec; - udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket.close(ec); - tcp_socket.close(ec); - -} - -/* - * @test Send a message with an invalid protocol version, invalid message type - * and invalid return code via UDP to the test master - * one time as client and one time as service. Ensure that message with the - * WRONG_PROTOCOL_VERSION is sent back in both cases - */ -TEST_F(malicious_data, wrong_header_fields_udp) -{ - std::promise remote_client_subscribed; - std::promise offer_received; - - boost::asio::ip::udp::socket udp_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - boost::asio::ip::udp::socket udp_socket_service(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 40001)); - - boost::asio::ip::udp::endpoint udp_client_info; - boost::asio::ip::udp::endpoint udp_service_info; - - - std::thread sd_receive_thread([&](){ - std::atomic keep_receiving(true); - std::vector receive_buffer(4096); - std::vector its_received_events; - std::atomic service_offered(false); - std::atomic client_subscribed(false); - - // join the sd multicast group 224.0.24.1 - udp_socket.set_option(boost::asio::ip::multicast::join_group( - boost::asio::ip::address::from_string("224.0.24.1").to_v4())); - - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = udp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - ADD_FAILURE() << __func__ << " error: " << error.message(); - return; - } else { - vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], - receive_buffer[VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], - receive_buffer[VSOMEIP_METHOD_POS_MAX]); - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_EQ(1u, sd_msg.get_entries().size()); - for (const auto& e : sd_msg.get_entries()) { - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { - EXPECT_TRUE(e->is_eventgroup_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); - EXPECT_EQ(1,e->get_num_options(1)); - EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); - EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); - EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); - EXPECT_EQ(1u, sd_msg.get_options().size()); - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); - } - std::shared_ptr op = sd_msg.get_options().front(); - EXPECT_EQ(op->get_type(), vsomeip::sd::option_type_e::IP4_ENDPOINT); - EXPECT_EQ(op->get_length(), 9u); - if (op->get_type() == vsomeip::sd::option_type_e::IP4_ENDPOINT) { - std::shared_ptr ip_op - = std::static_pointer_cast(op); - EXPECT_EQ(vsomeip::sd::layer_four_protocol_e::UDP, ip_op->get_layer_four_protocol()); - udp_client_info = boost::asio::ip::udp::endpoint( - boost::asio::ip::address_v4(ip_op->get_address()), - ip_op->get_port()); - } - - remote_client_subscribed.set_value(); - client_subscribed = true; - } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { - EXPECT_TRUE(e->is_service_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); - EXPECT_EQ(2,e->get_num_options(1)); - EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); - EXPECT_EQ(malicious_data_test::service.service_id + 1u, e->get_service()); - EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); - EXPECT_EQ(2u, sd_msg.get_options().size()); - if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_EQ(0u, its_casted_entry->get_minor_version()); - } - for (const auto& op : sd_msg.get_options()) { - EXPECT_EQ(op->get_type(), vsomeip::sd::option_type_e::IP4_ENDPOINT); - EXPECT_EQ(op->get_length(), 9u); - if (op->get_type() == vsomeip::sd::option_type_e::IP4_ENDPOINT) { - std::shared_ptr ip_op - = std::static_pointer_cast(op); - if (ip_op->get_layer_four_protocol() == vsomeip::sd::layer_four_protocol_e::UDP) { - EXPECT_EQ(vsomeip::sd::layer_four_protocol_e::UDP, ip_op->get_layer_four_protocol()); - udp_service_info = boost::asio::ip::udp::endpoint( - boost::asio::ip::address_v4(ip_op->get_address()), - ip_op->get_port()); - } - } - } - offer_received.set_value(); - service_offered = true; - } - } - if (service_offered && client_subscribed) { - keep_receiving = false; - } - } else { - ADD_FAILURE() << " received non-sd message"; - } - } - } - }); - - std::thread send_thread([&]() { - try { - boost::system::error_code ec; - udp_socket_service.set_option(boost::asio::socket_base::reuse_address(true), ec); - boost::asio::detail::throw_error(ec, "udp_socket_service set_option"); - - // offer the service - std::uint8_t its_offer_service_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x30, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, // length entries array - 0x01, 0x00, 0x00, 0x20, - 0x33, 0x44, 0x00, 0x01, // service / instance - 0x00, 0xff, 0xff, 0xff, // major / ttl - 0x00, 0x00, 0x00, 0x00, // minor - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // slave address - 0x00, 0x11, 0x9c, 0x41, // offer via udp - }; - boost::asio::ip::address its_local_address = - boost::asio::ip::address::from_string(std::string(local_address)); - std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); - - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30490); - udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); - - // wait until client subscribed - if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Client didn't subscribe within time"; - } - - // wait until a offer was received - if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive offer within time"; - } - - // send malicious data as server (wrong protocol version) - std::uint8_t wrong_protocol_data[] = { - 0x33, 0x44, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x08, - 0xAA, 0xAA, 0xCA, 0xFE, - 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA - }; - udp_socket_service.send_to(boost::asio::buffer(wrong_protocol_data), udp_client_info); - - std::uint8_t wrong_message_type_data[] = { - 0x33, 0x44, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x08, - 0xBB, 0xBB, 0xCA, 0xFE, - 0x01, 0x00, 0xBB, 0x00 // message type set to 0xBB - }; - udp_socket_service.send_to(boost::asio::buffer(wrong_message_type_data), udp_client_info); - - std::uint8_t wrong_return_code_data[] = { - 0x33, 0x44, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x08, - 0xCC, 0xCC, 0xCA, 0xFE, - 0x01, 0x00, 0x00, 0xCC // return code set to 0xCC - }; - udp_socket_service.send_to(boost::asio::buffer(wrong_return_code_data), udp_client_info); - - std::uint8_t all_wrong_data[] = { - 0x33, 0x44, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x08, - 0xAA, 0xAA, 0xCA, 0xFE, - 0xAA, 0x00, 0xBB, 0xCC - }; - udp_socket_service.send_to(boost::asio::buffer(all_wrong_data), udp_client_info); - - udp_socket_service.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket_service.close(ec); - - // establish second UDP connection as client and send malicious data as well - std::atomic error_response_as_client_received(false); - - boost::asio::ip::udp::socket udp_socket_client(io_); - boost::asio::ip::udp::socket::endpoint_type remote( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket_client.open(remote.protocol()); - udp_socket_client.connect(remote); - - - std::thread udp_client_receive_thread([&]() { - std::atomic keep_receiving(true); - std::function receive; - std::vector receive_buffer(4096); - - auto receive_cbk = [&](const boost::system::error_code& _error, - std::size_t bytes_transferred) { - if (!_error) { - vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - std::shared_ptr its_message(its_deserializer.deserialize_message()); - EXPECT_EQ(0x3345, its_message->get_service()); - EXPECT_EQ(0x1, its_message->get_method()); - EXPECT_EQ(0xCCCC, its_message->get_client()); - EXPECT_EQ(0xDDDD, its_message->get_session()); - EXPECT_EQ(vsomeip::return_code_e::E_WRONG_PROTOCOL_VERSION, its_message->get_return_code()); - EXPECT_EQ(vsomeip::message_type_e::MT_ERROR, its_message->get_message_type()); - error_response_as_client_received = true; - keep_receiving = false; - } else { - ADD_FAILURE() << __func__ << ":" << __LINE__ << " error: " << _error.message(); - return; - } - }; - - receive = [&]() { - udp_socket_client.async_receive(boost::asio::buffer(receive_buffer, receive_buffer.capacity()), - receive_cbk); - }; - - while (keep_receiving) { - receive(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - }); - - // send malicious data as client (too long length and wrong protocol version) - std::uint8_t wrong_protocol_client_data[] = { - 0x33, 0x45, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x08, - 0xCC, 0xCC, 0xDD, 0xDD, - 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA - }; - udp_socket_client.send_to(boost::asio::buffer(wrong_protocol_client_data), udp_service_info); - - std::uint8_t wrong_message_type_client_data[] = { - 0x33, 0x45, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x08, - 0xCC, 0xCC, 0xDD, 0xDD, - 0x01, 0x00, 0xBB, 0x00 // message type set to 0xBB - }; - udp_socket_client.send_to(boost::asio::buffer(wrong_message_type_client_data), udp_service_info); - - std::uint8_t wrong_return_code_client_data[] = { - 0x33, 0x45, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x08, - 0xCC, 0xCC, 0xDD, 0xDD, - 0x01, 0x00, 0x00, 0xCC // return code set to 0xCC - }; - udp_socket_client.send_to(boost::asio::buffer(wrong_return_code_client_data), udp_service_info); - - std::uint8_t all_wrong_client_data[] = { - 0x33, 0x45, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x08, - 0xCC, 0xCC, 0xDD, 0xDD, - 0xAA, 0x00, 0xBB, 0xCC - }; - udp_socket_client.send_to(boost::asio::buffer(all_wrong_client_data), udp_service_info); - - - udp_client_receive_thread.join(); - EXPECT_TRUE(error_response_as_client_received); - - udp_socket_client.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket_client.close(ec); - - // call shutdown method - std::uint8_t shutdown_call[] = { - 0x33, 0x45, 0x14, 0x04, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); - udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); - udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket2.close(ec); - } catch (const std::exception& _e) { - ADD_FAILURE() << "catched exception: " << _e.what(); - } - - }); - - send_thread.join(); - sd_receive_thread.join(); - boost::system::error_code ec; - udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket.close(ec); -} - -#ifndef _WIN32 -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - if(argc < 3) { - std::cerr << "Please pass an target, local IP address and test mode to this binary like: " - << argv[0] << " 10.0.3.1 10.0.3.202 EVENTS" << std::endl; - exit(1); - } - remote_address = argv[1]; - local_address = argv[2]; - std::string its_testmode = argv[3]; - if (its_testmode == std::string("MALICIOUS_EVENTS")) { - ::testing::GTEST_FLAG(filter) = "*send_malicious_events"; - } else if (its_testmode == std::string("PROTOCOL_VERSION")) { - ::testing::GTEST_FLAG(filter) = "*send_wrong_protocol_version"; - } else if (its_testmode == std::string("MESSAGE_TYPE")) { - ::testing::GTEST_FLAG(filter) = "*send_wrong_message_type"; - } else if (its_testmode == std::string("RETURN_CODE")) { - ::testing::GTEST_FLAG(filter) = "*send_wrong_return_code"; - } else if (its_testmode == std::string("WRONG_HEADER_FIELDS_UDP")) { - ::testing::GTEST_FLAG(filter) = "*wrong_header_fields_udp"; - } - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/malicious_data_tests/malicious_data_test_service.cpp b/test/malicious_data_tests/malicious_data_test_service.cpp deleted file mode 100644 index 735f0f6..0000000 --- a/test/malicious_data_tests/malicious_data_test_service.cpp +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "malicious_data_test_globals.hpp" - -class malicious_data_test_service { -public: - malicious_data_test_service(struct malicious_data_test::service_info _service_info, malicious_data_test::test_mode_e _testmode) : - service_info_(_service_info), - testmode_(_testmode), - app_(vsomeip::runtime::get()->create_application("malicious_data_test_service")), - wait_until_registered_(true), - wait_until_shutdown_method_called_(true), - received_events_(0), - received_methodcalls_(0), - offer_thread_(std::bind(&malicious_data_test_service::run, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&malicious_data_test_service::on_state, this, - std::placeholders::_1)); - - std::set its_eventgroups; - its_eventgroups.insert(_service_info.eventgroup_id); - app_->request_event(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_eventgroups, vsomeip::event_type_e::ET_EVENT, - vsomeip::reliability_type_e::RT_UNKNOWN); - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, service_info_.shutdown_method_id, - std::bind(&malicious_data_test_service::on_shutdown_method_called, this, - std::placeholders::_1)); - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.event_id, - std::bind(&malicious_data_test_service::on_event, this, - std::placeholders::_1)); - - app_->register_message_handler(static_cast(service_info_.service_id + 1u), - service_info_.instance_id, 0x1, - std::bind(&malicious_data_test_service::on_message, this, - std::placeholders::_1)); - - // request service of client - app_->request_service(service_info_.service_id, service_info_.instance_id); - app_->subscribe(service_info_.service_id, service_info_.instance_id, - service_info_.eventgroup_id, 0, - service_info_.event_id); - - app_->start(); - } - - ~malicious_data_test_service() { - if (testmode_ == malicious_data_test::test_mode_e::MALICIOUS_EVENTS) { - EXPECT_EQ(9u, received_events_); - EXPECT_EQ(9u, received_methodcalls_); - } - offer_thread_.join(); - } - - void offer() { - app_->offer_service(static_cast(service_info_.service_id + 1u), 0x1); - } - - void stop() { - app_->stop_offer_service(static_cast(service_info_.service_id + 1u), 0x1); - app_->clear_all_handler(); - app_->stop(); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_shutdown_method_called(const std::shared_ptr &_message) { - app_->send(vsomeip::runtime::get()->create_response(_message)); - VSOMEIP_WARNING << "************************************************************"; - VSOMEIP_WARNING << "Shutdown method called -> going down!"; - VSOMEIP_WARNING << "************************************************************"; - std::lock_guard its_lock(mutex_); - wait_until_shutdown_method_called_ = false; - condition_.notify_one(); - } - - void on_event(const std::shared_ptr &_message) { - EXPECT_EQ(service_info_.service_id, _message->get_service()); - EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - EXPECT_EQ(service_info_.event_id, _message->get_method()); - EXPECT_EQ(std::uint32_t(0x7F), _message->get_length()); - received_events_++; - } - - void on_message(const std::shared_ptr &_message) { - EXPECT_EQ(static_cast(service_info_.service_id + 1u), _message->get_service()); - EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - EXPECT_EQ(vsomeip::method_t(0x1), _message->get_method()); - EXPECT_EQ(std::uint32_t(0x7F), _message->get_length()); - received_methodcalls_++; - } - - void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - - while (wait_until_shutdown_method_called_) { - condition_.wait(its_lock); - } - stop(); - } - -private: - struct malicious_data_test::service_info service_info_; - malicious_data_test::test_mode_e testmode_; - std::shared_ptr app_; - - bool wait_until_registered_; - bool wait_until_shutdown_method_called_; - std::uint32_t received_events_; - std::uint32_t received_methodcalls_; - std::mutex mutex_; - std::condition_variable condition_; - std::thread offer_thread_; -}; - -malicious_data_test::test_mode_e its_testmode(malicious_data_test::test_mode_e::MALICIOUS_EVENTS); - -TEST(someip_malicious_data_test, block_subscription_handler) -{ - malicious_data_test_service its_sample(malicious_data_test::service, its_testmode); -} - - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - std::string its_passed_testmode = argv[1]; - if (its_passed_testmode == std::string("MALICIOUS_EVENTS")) { - its_testmode = malicious_data_test::test_mode_e::MALICIOUS_EVENTS; - } else if (its_passed_testmode == std::string("PROTOCOL_VERSION")) { - its_testmode = malicious_data_test::test_mode_e::PROTOCOL_VERSION; - } else if (its_passed_testmode == std::string("MESSAGE_TYPE")) { - its_testmode = malicious_data_test::test_mode_e::MESSAGE_TYPE; - } else if (its_passed_testmode == std::string("RETURN_CODE")) { - its_testmode = malicious_data_test::test_mode_e::RETURN_CODE; - } else if (its_passed_testmode == std::string("WRONG_HEADER_FIELDS_UDP")) { - its_testmode = malicious_data_test::test_mode_e::WRONG_HEADER_FIELDS_UDP; - } - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/network_tests/CMakeLists.txt b/test/network_tests/CMakeLists.txt new file mode 100644 index 0000000..6a14860 --- /dev/null +++ b/test/network_tests/CMakeLists.txt @@ -0,0 +1,4391 @@ +# Copyright (C) 2015-2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +set (VSOMEIP_NAME vsomeip3) + +# Add the gtest header files to the include files +include_directories( + . + ${gtest_SOURCE_DIR}/include +) + +set(TEST_LINK_LIBRARIES gtest) + +set(NETWORK_TEST_BIN_DIR ${PROJECT_BINARY_DIR}/test/network_tests) +set(NETWORK_TEST_SRC_DIR ${PROJECT_SOURCE_DIR}/test/network_tests) + +# Function to copy files into the build directory (or anywhere else) +# On unixoid systems this function will create symlinks instead +# SOURCE_PATH: Path to the file which should be copied +# DESTINATION_PATH: destination file +# TARGET_TO_DEPEND: The copying of the file will be added as +# a dependency to this target +function(copy_to_builddir SOURCE_PATH DESTINATION_PATH TARGET_TO_DEPEND) + if(${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR NOT ${TEST_SYMLINK_CONFIG_FILES}) + ADD_CUSTOM_COMMAND( + OUTPUT "${DESTINATION_PATH}" + COMMAND ${CMAKE_COMMAND} -E copy "${SOURCE_PATH}" "${DESTINATION_PATH}" + DEPENDS "${SOURCE_PATH}" + COMMENT "Copying \"${SOURCE_PATH}\" into build directory" + ) + else() + if(${TEST_SYMLINK_CONFIG_FILES_RELATIVE}) + ADD_CUSTOM_COMMAND( + OUTPUT "${DESTINATION_PATH}" + # Create a relative link + COMMAND ln -s -r "${SOURCE_PATH}" "${DESTINATION_PATH}" + DEPENDS "${SOURCE_PATH}" + COMMENT "Symlinking \"${SOURCE_PATH}\" into build directory" + ) + else() + ADD_CUSTOM_COMMAND( + OUTPUT "${DESTINATION_PATH}" + # Create an absolute link + COMMAND ${CMAKE_COMMAND} -E create_symlink "${SOURCE_PATH}" "${DESTINATION_PATH}" + DEPENDS "${SOURCE_PATH}" + COMMENT "Symlinking \"${SOURCE_PATH}\" into build directory" + ) + endif() + endif() + # Add a random number to the end of the string to avoid problems with + # duplicate filenames + set(FILENAME "") + get_filename_component(FILENAME ${SOURCE_PATH} NAME ) + string(RANDOM LENGTH 4 ALPHABET 0123456789 RANDOMNUMBER) + if (${CMAKE_SYSTEM_NAME} MATCHES "Windows") + ADD_CUSTOM_TARGET(copy_${FILENAME}_${RANDOMNUMBER} + DEPENDS "${DESTINATION_PATH}" + ) + ADD_DEPENDENCIES(${TARGET_TO_DEPEND} copy_${FILENAME}_${RANDOMNUMBER}) + else() + ADD_CUSTOM_TARGET(symlink_${FILENAME}_${RANDOMNUMBER} + DEPENDS "${DESTINATION_PATH}" + ) + ADD_DEPENDENCIES(${TARGET_TO_DEPEND} symlink_${FILENAME}_${RANDOMNUMBER}) + endif() +endfunction() + +############################################################################## +# configuration-test +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_CONFIGURATION configuration-test) + + add_executable(${TEST_CONFIGURATION} + configuration_tests/configuration-test.cpp + ${PROJECT_SOURCE_DIR}/implementation/plugin/src/plugin_manager_impl.cpp + ${PROJECT_SOURCE_DIR}/test/common/utility.cpp + ) + target_link_libraries(${TEST_CONFIGURATION} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # The following will make sure that ${TEST_CONFIGURATION_CONFIG_FILE} is copied + # from the config folder into the test folder in the builddirectory + # This makes it possible to call the configuration test within the build directory + set(TEST_CONFIGURATION_CONFIG_FILE configuration-test.json) + set(TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE configuration-test-deprecated.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/configuration_tests/${TEST_CONFIGURATION_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CONFIGURATION_CONFIG_FILE} + ${TEST_CONFIGURATION} + ) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/configuration_tests/${TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CONFIGURATION_DEPRECATED_CONFIG_FILE} + ${TEST_CONFIGURATION} + ) +endif() +############################################################################## +# application test +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_APPLICATION application_test) + + add_executable(${TEST_APPLICATION} application_tests/${TEST_APPLICATION}.cpp) + target_link_libraries(${TEST_APPLICATION} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_APPLICATION_SINGLE_PROCESS_NAME ${TEST_APPLICATION}_single_process) + add_executable(${TEST_APPLICATION_SINGLE_PROCESS_NAME} application_tests/${TEST_APPLICATION_SINGLE_PROCESS_NAME}.cpp) + target_link_libraries(${TEST_APPLICATION_SINGLE_PROCESS_NAME} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_APPLICATION_AVAILABILITY_NAME ${TEST_APPLICATION}_availability) + add_executable(${TEST_APPLICATION_AVAILABILITY_NAME} application_tests/${TEST_APPLICATION_AVAILABILITY_NAME}.cpp) + target_link_libraries(${TEST_APPLICATION_AVAILABILITY_NAME} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE ${TEST_APPLICATION}_single_process.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_SINGLE_PROCESS_CONFIGURATION_FILE} + ${TEST_APPLICATION}_single_process + ) + + set(TEST_APPLICATION_CONFIGURATION_FILE ${TEST_APPLICATION}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/application_tests/conf/${TEST_APPLICATION_CONFIGURATION_FILE}.in + ${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_CONFIGURATION_FILE} + ${TEST_APPLICATION} + ) + + set(TEST_APPLICATION_CONFIGURATION_FILE_DAEMON ${TEST_APPLICATION}_daemon.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/application_tests/conf/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON}.in + ${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_CONFIGURATION_FILE_DAEMON} + ${TEST_APPLICATION} + ) + + set(TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE ${TEST_APPLICATION}_no_dispatch_threads.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/application_tests/conf/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE}.in + ${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE} + ${TEST_APPLICATION} + ) + + set(TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON ${TEST_APPLICATION}_no_dispatch_threads_daemon.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/application_tests/conf/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON}.in + ${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_NO_DISPATCH_CONFIGURATION_FILE_DAEMON} + ${TEST_APPLICATION} + ) + + set(TEST_APPLICATION_STARTER ${TEST_APPLICATION}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_STARTER} + ${TEST_APPLICATION} + ) + + set(TEST_APPLICATION_SINGLE_PROCESS_STARTER ${TEST_APPLICATION}_single_process_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} + ${TEST_APPLICATION}_single_process + ) + + set(TEST_APPLICATION_AVAILABILITY_STARTER ${TEST_APPLICATION_AVAILABILITY_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/application_tests/${TEST_APPLICATION_AVAILABILITY_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_AVAILABILITY_STARTER} + ${TEST_APPLICATION_SINGLE_PROCESS_NAME} + ) +endif() +############################################################################## +# magic-cookies-test-client +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_MAGIC_COOKIES_NAME magic_cookies_test) + + set(TEST_MAGIC_COOKIES_CLIENT ${TEST_MAGIC_COOKIES_NAME}_client) + add_executable(${TEST_MAGIC_COOKIES_CLIENT} magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT}.cpp) + target_link_libraries(${TEST_MAGIC_COOKIES_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_MAGIC_COOKIES_SERVICE ${TEST_MAGIC_COOKIES_NAME}_service) + add_executable(${TEST_MAGIC_COOKIES_SERVICE} magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE}.cpp) + target_link_libraries(${TEST_MAGIC_COOKIES_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE ${TEST_MAGIC_COOKIES_CLIENT}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/conf/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_CLIENT_CONFIG_FILE} + ${TEST_MAGIC_COOKIES_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT ${TEST_MAGIC_COOKIES_CLIENT}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_CLIENT_START_SCRIPT} + ${TEST_MAGIC_COOKIES_CLIENT} + ) + + set(TEST_MAGIC_COOKIES_SERVICE magic_cookies_test_service) + # Copy config file for service into $BUILDDIR/test + set(TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE ${TEST_MAGIC_COOKIES_SERVICE}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/conf/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_SERVICE_CONFIG_FILE} + ${TEST_MAGIC_COOKIES_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT ${TEST_MAGIC_COOKIES_SERVICE}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_SERVICE_START_SCRIPT} + ${TEST_MAGIC_COOKIES_CLIENT} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_MAGIC_COOKIES_STARTER ${TEST_MAGIC_COOKIES_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/magic_cookies_tests/${TEST_MAGIC_COOKIES_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_STARTER} + ${TEST_MAGIC_COOKIES_CLIENT} + ) +endif() +############################################################################## +# someip-header-factory-test +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_HEADER_FACTORY_NAME header_factory_test) + + set(TEST_HEADER_FACTORY header_factory_test) + add_executable(${TEST_HEADER_FACTORY} header_factory_tests/header_factory_test.cpp) + target_link_libraries(${TEST_HEADER_FACTORY} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${TEST_LINK_LIBRARIES} + ) + + ############################################################################## + # Now comes the second part of the header factory test which consists of ouf + # a client and a service both with settings file and bash scripts to start them + set(TEST_HEADER_FACTORY_CLIENT header_factory_test_client) + add_executable(${TEST_HEADER_FACTORY_CLIENT} header_factory_tests/${TEST_HEADER_FACTORY_CLIENT}.cpp) + target_link_libraries(${TEST_HEADER_FACTORY_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE ${TEST_HEADER_FACTORY_CLIENT}.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_CLIENT_CONFIG_FILE} + ${TEST_HEADER_FACTORY_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_HEADER_FACTORY_CLIENT_START_SCRIPT ${TEST_HEADER_FACTORY_CLIENT}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_CLIENT_START_SCRIPT} + ${TEST_HEADER_FACTORY_CLIENT} + ) + + set(TEST_HEADER_FACTORY_SERVICE header_factory_test_service) + add_executable(${TEST_HEADER_FACTORY_SERVICE} header_factory_tests/${TEST_HEADER_FACTORY_SERVICE}.cpp) + target_link_libraries(${TEST_HEADER_FACTORY_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE ${TEST_HEADER_FACTORY_SERVICE}.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_SERVICE_CONFIG_FILE} + ${TEST_HEADER_FACTORY_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_HEADER_FACTORY_SERVICE_START_SCRIPT ${TEST_HEADER_FACTORY_SERVICE}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_SERVICE_START_SCRIPT} + ${TEST_HEADER_FACTORY_SERVICE} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_HEADER_FACTORY_STARTER header_factory_test_send_receive_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/header_factory_tests/${TEST_HEADER_FACTORY_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_STARTER} + ${TEST_HEADER_FACTORY_CLIENT} + ) +endif() +############################################################################## +# routing-test +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_LOCAL_ROUTING_NAME local_routing_test) + + set(TEST_LOCAL_ROUTING_SERVICE local_routing_test_service) + add_executable(${TEST_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_LOCAL_ROUTING_SERVICE}.cpp) + target_link_libraries(${TEST_LOCAL_ROUTING_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_LOCAL_ROUTING_SERVICE}.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + ${TEST_LOCAL_ROUTING_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_LOCAL_ROUTING_SERVICE}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} + ${TEST_LOCAL_ROUTING_SERVICE} + ) + + set(TEST_LOCAL_ROUTING_CLIENT local_routing_test_client) + add_executable(${TEST_LOCAL_ROUTING_CLIENT} routing_tests/${TEST_LOCAL_ROUTING_CLIENT}.cpp) + target_link_libraries(${TEST_LOCAL_ROUTING_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_LOCAL_ROUTING_CLIENT}.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + ${TEST_LOCAL_ROUTING_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_LOCAL_ROUTING_CLIENT}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} + ${TEST_LOCAL_ROUTING_CLIENT} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_LOCAL_ROUTING_STARTER local_routing_test_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/routing_tests/conf/${TEST_LOCAL_ROUTING_STARTER}.in + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_STARTER} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_STARTER} + ${TEST_LOCAL_ROUTING_CLIENT} + ) + + ############################################################################## + set(TEST_EXTERNAL_LOCAL_ROUTING_NAME external_local_routing_test) + set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE external_local_routing_test_service) + add_executable(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}.cpp) + target_link_libraries(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/routing_tests/conf/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE_START_SCRIPT} + ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} + ) + + # Copy bashscript to start external client into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT external_local_routing_test_client_external) + set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_START_SCRIPT} + ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/routing_tests/conf/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_ROUTING_STARTER external_local_routing_test_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} + ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} + ) +else() + set(TEST_LOCAL_ROUTING_NAME local_routing_test) + + set(TEST_LOCAL_ROUTING_SERVICE local_routing_test_service) + add_executable(${TEST_LOCAL_ROUTING_SERVICE} routing_tests/${TEST_LOCAL_ROUTING_SERVICE}.cpp) + target_link_libraries(${TEST_LOCAL_ROUTING_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE ${TEST_LOCAL_ROUTING_SERVICE}.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_SERVICE_CONFIG_FILE} + ${TEST_LOCAL_ROUTING_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT ${TEST_LOCAL_ROUTING_SERVICE}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_SERVICE_START_SCRIPT} + ${TEST_LOCAL_ROUTING_SERVICE} + ) + + set(TEST_LOCAL_ROUTING_CLIENT local_routing_test_client) + add_executable(${TEST_LOCAL_ROUTING_CLIENT} routing_tests/${TEST_LOCAL_ROUTING_CLIENT}.cpp) + target_link_libraries(${TEST_LOCAL_ROUTING_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE ${TEST_LOCAL_ROUTING_CLIENT}.json) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_CLIENT_CONFIG_FILE} + ${TEST_LOCAL_ROUTING_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT ${TEST_LOCAL_ROUTING_CLIENT}_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_CLIENT_START_SCRIPT} + ${TEST_LOCAL_ROUTING_CLIENT} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_LOCAL_ROUTING_STARTER local_routing_test_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/routing_tests/conf/${TEST_LOCAL_ROUTING_STARTER}.bat.in + ${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_STARTER} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/routing_tests/${TEST_LOCAL_ROUTING_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_STARTER} + ${TEST_LOCAL_ROUTING_CLIENT} + ) +endif() +############################################################################## +# restart_routing-test +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_RESTART_ROUTING_NAME restart_routing_test) + + set(TEST_RESTART_ROUTING_SERVICE restart_routing_test_service) + add_executable(${TEST_RESTART_ROUTING_SERVICE} restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE}.cpp) + target_link_libraries(${TEST_RESTART_ROUTING_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE ${TEST_RESTART_ROUTING_SERVICE}.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_SERVICE_CONFIG_FILE} + ${TEST_RESTART_ROUTING_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_RESTART_ROUTING_SERVICE_START_SCRIPT ${TEST_RESTART_ROUTING_SERVICE}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_SERVICE_START_SCRIPT} + ${TEST_RESTART_ROUTING_SERVICE} + ) + + set(TEST_RESTART_ROUTING_CLIENT restart_routing_test_client) + add_executable(${TEST_RESTART_ROUTING_CLIENT} + restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT}.cpp + ) + target_link_libraries(${TEST_RESTART_ROUTING_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE ${TEST_RESTART_ROUTING_CLIENT}.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_CLIENT_CONFIG_FILE} + ${TEST_RESTART_ROUTING_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_RESTART_ROUTING_CLIENT_START_SCRIPT ${TEST_RESTART_ROUTING_CLIENT}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_CLIENT_START_SCRIPT} + ${TEST_RESTART_ROUTING_CLIENT} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_RESTART_ROUTING_STARTER restart_routing_test_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_STARTER} + ${TEST_RESTART_ROUTING_CLIENT} + ) + + # Copy config file for autoconfig into $BUILDDIR/test + set(TEST_RESTART_ROUTING_AUTO_CONFIG_FILE ${TEST_RESTART_ROUTING_NAME}_autoconfig.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/restart_routing_tests/${TEST_RESTART_ROUTING_AUTO_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_AUTO_CONFIG_FILE} + ${TEST_RESTART_ROUTING_CLIENT} + ) +endif() + +############################################################################## +# security test +############################################################################## + +if (${TEST_SECURITY}) + if(NOT ${TESTS_BAT}) + set(TEST_SECURITY_NAME security_test) + set(TEST_SECURITY_SERVICE security_test_service) + set(TEST_SECURITY_CLIENT security_test_client) + + add_executable(${TEST_SECURITY_SERVICE} security_tests/${TEST_SECURITY_SERVICE}.cpp) + target_link_libraries(${TEST_SECURITY_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_SECURITY_LOCAL_CONFIG_FILE ${TEST_SECURITY_NAME}_local_config.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_LOCAL_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_LOCAL_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_LOCAL_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_LOCAL_CONFIG_FILE} + ${TEST_SECURITY_SERVICE} + ) + + # Copy service config file for external allow tests into $BUILDDIR/test + set(TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_SECURITY_NAME}_config_service_external_allow.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL}.in + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL} + ${TEST_SECURITY_SERVICE} + ) + + # Copy client config file for external allow tests into $BUILDDIR/test + set(TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_SECURITY_NAME}_config_client_external_allow.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL}.in + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL} + ${TEST_SECURITY_SERVICE} + ) + + # Copy service config file for external deny tests into $BUILDDIR/test + set(TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY ${TEST_SECURITY_NAME}_config_service_external_deny.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY}.in + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_SERVICE_CONFIG_FILE_EXTERNAL_DENY} + ${TEST_SECURITY_SERVICE} + ) + + # Copy client config file for external deny tests into $BUILDDIR/test + set(TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY ${TEST_SECURITY_NAME}_config_client_external_deny.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/security_tests/conf/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY}.in + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_CLIENT_CONFIG_FILE_EXTERNAL_DENY} + ${TEST_SECURITY_SERVICE} + ) + + # Copy bashscript to start local test into $BUILDDIR/test + set(TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT ${TEST_SECURITY_NAME}_local_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} + ${TEST_SECURITY_SERVICE} + ) + + # Copy bashscript to start external tests (master) into $BUILDDIR/test + set(TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT ${TEST_SECURITY_NAME}_external_master_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} + ${TEST_SECURITY_SERVICE} + ) + + # Copy bashscript to start external tests (slave) into $BUILDDIR/test + set(TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT ${TEST_SECURITY_NAME}_external_slave_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/security_tests/${TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_EXTERNAL_SLAVE_START_SCRIPT} + ${TEST_SECURITY_SERVICE} + ) + + add_executable(${TEST_SECURITY_CLIENT} + security_tests/${TEST_SECURITY_CLIENT}.cpp + ) + target_link_libraries(${TEST_SECURITY_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + endif() +endif() + +############################################################################## +# payload-test +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_LOCAL_PAYLOAD_NAME local_payload_test) + + set(TEST_PAYLOAD_SERVICE payload_test_service) + add_executable(${TEST_PAYLOAD_SERVICE} payload_tests/${TEST_PAYLOAD_SERVICE}.cpp) + target_link_libraries(${TEST_PAYLOAD_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service into $BUILDDIR/test + set(TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE local_${TEST_PAYLOAD_SERVICE}.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} + ${TEST_PAYLOAD_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT local_${TEST_PAYLOAD_SERVICE}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} + ${TEST_PAYLOAD_SERVICE} + ) + + set(TEST_PAYLOAD_CLIENT payload_test_client) + add_executable(${TEST_PAYLOAD_CLIENT} + payload_tests/${TEST_PAYLOAD_CLIENT}.cpp + payload_tests/stopwatch.cpp + ) + target_link_libraries(${TEST_PAYLOAD_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client into $BUILDDIR/test + set(TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE local_${TEST_PAYLOAD_CLIENT}.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} + ${TEST_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT local_${TEST_PAYLOAD_CLIENT}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_CLIENT_START_SCRIPT} + ${TEST_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_LOCAL_PAYLOAD_STARTER local_payload_test_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_STARTER} + ${TEST_PAYLOAD_CLIENT} + ) + + ############################################################################## + set(TEST_EXTERNAL_LOCAL_PAYLOAD_NAME external_local_payload_test) + set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE external_local_payload_test_service) + + # Copy config file for service into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CONFIG_FILE} + ${TEST_PAYLOAD_SERVICE} + ) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_START_SCRIPT} + ${TEST_PAYLOAD_SERVICE} + ) + + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL external_local_payload_test_client_local) + + # Copy config file for client into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_CONFIG_FILE} + ${TEST_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_START_SCRIPT} + ${TEST_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME external_local_payload_test_client_local) + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} + ${TEST_PAYLOAD_CLIENT} + ) + ############################################################################## + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME external_local_payload_test_client_external) + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL external_local_payload_test_client_external) + + # Copy config file for client into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/payload_tests/conf/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_CONFIG_FILE} + ${TEST_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start client into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_START_SCRIPT} + ${TEST_PAYLOAD_CLIENT} + ) + + set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENT_EXTERNAL external_local_payload_test_service_client_external) + + # Copy bashscript to start service into $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT ${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENT_EXTERNAL}_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_SERVICE_CLIENTT_EXTERNAL_START_SCRIPT} + ${TEST_PAYLOAD_SERVICE} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} + ${TEST_PAYLOAD_CLIENT} + ) + + ############################################################################## + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME external_local_payload_test_client_local_and_external) + set(TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} + ${TEST_PAYLOAD_CLIENT} + ) + + ############################################################################## + set(TEST_LOCAL_PAYLOAD_HUGE_NAME local_payload_test_huge_payload) + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_LOCAL_PAYLOAD_HUGE_STARTER ${TEST_LOCAL_PAYLOAD_HUGE_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/payload_tests/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} + ${TEST_PAYLOAD_CLIENT} + ) +endif() + +############################################################################## +# big_payload_test +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_BIG_PAYLOAD_NAME big_payload_test) + + set(TEST_BIG_PAYLOAD_SERVICE big_payload_test_service) + add_executable(${TEST_BIG_PAYLOAD_SERVICE} big_payload_tests/${TEST_BIG_PAYLOAD_SERVICE}.cpp) + target_link_libraries(${TEST_BIG_PAYLOAD_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_BIG_PAYLOAD_CLIENT big_payload_test_client) + add_executable(${TEST_BIG_PAYLOAD_CLIENT} big_payload_tests/${TEST_BIG_PAYLOAD_CLIENT}.cpp) + target_link_libraries(${TEST_BIG_PAYLOAD_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local_queue_limited.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_QUEUE_LIMITED_LOCAL_BIG_PAYLOAD_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_local_random.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_RANDOM} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_limited.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_CONFIG_FILE_LIMITED} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local_tcp_client.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_local_tcp_service.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_tcp_client_limited.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_tcp_service_limited.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_tcp_client_queue_limited.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_local_tcp_service_queue_limited.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_local_tcp_client_random.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_local_tcp_service_random.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_tcp_client.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_tcp_service.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_tcp_client_limited_general.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_LIMITED} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED ${TEST_BIG_PAYLOAD_NAME}_tcp_service_limited_general.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_LIMITED} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_tcp_client_random.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_RANDOM} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM ${TEST_BIG_PAYLOAD_NAME}_tcp_service_random.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_RANDOM} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL ${TEST_BIG_PAYLOAD_NAME}_tcp_client_queue_limited_general.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_GENERAL} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL ${TEST_BIG_PAYLOAD_NAME}_tcp_service_queue_limited_general.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_GENERAL} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC ${TEST_BIG_PAYLOAD_NAME}_tcp_client_queue_limited_specific.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy config file for client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC ${TEST_BIG_PAYLOAD_NAME}_tcp_service_queue_limited_specific.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_CONFIG_FILE_QUEUE_LIMITED_SPECIFIC} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + # Copy config file for UDP client and service into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_udp_service.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_UDP_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE ${TEST_BIG_PAYLOAD_NAME}_udp_client.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/conf/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_UDP_CONFIG_FILE} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start client local to $BUILDDIR/test + set(TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_client_local_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} + ${TEST_BIG_PAYLOAD_CLIENT} + ) + + # Copy bashscript to start service local to $BUILDDIR/test + set(TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT ${TEST_BIG_PAYLOAD_NAME}_service_local_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_LOCAL_BIG_PAYLOAD_NAME big_payload_test_local) + set(TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM big_payload_test_local_random) + set(TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED big_payload_test_local_limited) + set(TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED big_payload_test_local_queue_limited) + set(TEST_LOCAL_BIG_PAYLOAD_STARTER ${TEST_LOCAL_BIG_PAYLOAD_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_BIG_PAYLOAD_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy bashscript to start client and server $BUILDDIR/test + set(TEST_LOCAL_TCP_BIG_PAYLOAD_NAME big_payload_test_local_tcp) + set(TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_RANDOM big_payload_test_local_tcp_random) + set(TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_LIMITED big_payload_test_local_tcp_limited) + set(TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_QUEUE_LIMITED big_payload_test_local_tcp_queue_limited) + # Copy starter as well as client/service start scripts for external tests + set(TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + set(TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_START_SCRIPT ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME}_service_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_SERVICE_START_SCRIPT} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + # Copy bashscript to start client for external test into $BUILDDIR/test + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME big_payload_test_external) + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM big_payload_test_external_random) + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED big_payload_test_external_limited) + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL big_payload_test_external_limited_general) + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL big_payload_test_external_queue_limited_general) + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC big_payload_test_external_queue_limited_specific) + set(TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP big_payload_test_external_udp) + + # Copy starter as well as client/service start scripts for external tests + set(TEST_EXTERNAL_BIG_PAYLOAD_STARTER ${TEST_EXTERNAL_BIG_PAYLOAD_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + set(TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT ${TEST_EXTERNAL_BIG_PAYLOAD_NAME}_service_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_SERVICE_START_SCRIPT} + ${TEST_BIG_PAYLOAD_SERVICE} + ) + + set(TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT ${TEST_EXTERNAL_BIG_PAYLOAD_NAME}_client_start.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/big_payload_tests/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_CLIENT_START_SCRIPT} + ${TEST_BIG_PAYLOAD_CLIENT} + ) +endif() + +############################################################################## +# client id tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_CLIENT_ID_NAME client_id_test) + set(TEST_CLIENT_ID_SERVICE ${TEST_CLIENT_ID_NAME}_service) + add_executable(${TEST_CLIENT_ID_SERVICE} client_id_tests/${TEST_CLIENT_ID_NAME}_service.cpp) + target_link_libraries(${TEST_CLIENT_ID_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_CLIENT_ID_UTILITY ${TEST_CLIENT_ID_NAME}_utility) + add_executable(${TEST_CLIENT_ID_UTILITY} + client_id_tests/${TEST_CLIENT_ID_UTILITY}.cpp + ${PROJECT_SOURCE_DIR}/implementation/utility/src/utility.cpp) + target_link_libraries(${TEST_CLIENT_ID_UTILITY} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config files for test into $BUILDDIR/test + set(TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_same_client_ids_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_same_client_ids_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_same_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_CLIENT_ID_NAME}_same_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/conf/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_CLIENT_ID_SERVICE} + ) + + set(TEST_CLIENT_ID_UTILITY_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_CONFIG_FILE} + ${TEST_CLIENT_ID_UTILITY} + ) + set(TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_511.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE} + ${TEST_CLIENT_ID_UTILITY} + ) + + set(TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_4095.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE} + ${TEST_CLIENT_ID_UTILITY} + ) + + set(TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_masked_127.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE} + ${TEST_CLIENT_ID_UTILITY} + ) + + set(TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE ${TEST_CLIENT_ID_NAME}_utility_discontinuous_masked_511.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE} + ${TEST_CLIENT_ID_UTILITY} + ) + + # copy starter scripts into builddir + set(TEST_CLIENT_ID_MASTER_STARTER ${TEST_CLIENT_ID_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_MASTER_STARTER} + ${TEST_CLIENT_ID_SERVICE} + ) + set(TEST_CLIENT_ID_SLAVE_STARTER ${TEST_CLIENT_ID_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/client_id_tests/${TEST_CLIENT_ID_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_SLAVE_STARTER} + ${TEST_CLIENT_ID_SERVICE} + ) +endif() + +############################################################################## +# debounce tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_DEBOUNCE_NAME debounce_test) + set(TEST_DEBOUNCE_CLIENT ${TEST_DEBOUNCE_NAME}_client) + add_executable(${TEST_DEBOUNCE_CLIENT} debounce_tests/${TEST_DEBOUNCE_CLIENT}.cpp) + target_link_libraries(${TEST_DEBOUNCE_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + set(TEST_DEBOUNCE_SERVICE ${TEST_DEBOUNCE_NAME}_service) + add_executable(${TEST_DEBOUNCE_SERVICE} debounce_tests/${TEST_DEBOUNCE_SERVICE}.cpp) + target_link_libraries(${TEST_DEBOUNCE_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # copy starter scripts into builddir + set(TEST_DEBOUNCE_MASTER_STARTER ${TEST_DEBOUNCE_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_MASTER_STARTER} + ${TEST_DEBOUNCE_SERVICE} + ) + set(TEST_DEBOUNCE_SLAVE_STARTER ${TEST_DEBOUNCE_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_SLAVE_STARTER} + ${TEST_DEBOUNCE_SERVICE} + ) + + # configure configurations and copy them into builddir + set(TEST_DEBOUNCE_MASTER_CONFIG_FILE ${TEST_DEBOUNCE_SERVICE}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/debounce_tests/conf/${TEST_DEBOUNCE_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_MASTER_CONFIG_FILE} + ${TEST_DEBOUNCE_SERVICE} + ) + set(TEST_DEBOUNCE_SLAVE_CONFIG_FILE ${TEST_DEBOUNCE_CLIENT}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/debounce_tests/conf/${TEST_DEBOUNCE_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/debounce_tests/${TEST_DEBOUNCE_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_SLAVE_CONFIG_FILE} + ${TEST_DEBOUNCE_SERVICE} + ) +endif() + +############################################################################## +# subscribe notify tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_SUBSCRIBE_NOTIFY_NAME subscribe_notify_test) + set(TEST_SUBSCRIBE_NOTIFY_SERVICE ${TEST_SUBSCRIBE_NOTIFY_NAME}_service) + add_executable(${TEST_SUBSCRIBE_NOTIFY_SERVICE} subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_NAME}_service.cpp) + target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config files for test into $BUILDDIR/test (local communication via UDS) + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_master_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + # copy starter scripts into builddir + set(TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + set(TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + # subscribe_notify_test_one_event_two_eventgroups + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME subscribe_notify_test_one_event_two_eventgroups) + + # service + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_service) + add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE}.cpp) + target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + # client + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_client) + add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} + subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT}.cpp) + target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} + ) + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ) + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ) + + # Copy config files for test into $BUILDDIR/test (local communication via TCP) + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_tcp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_tcp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_udp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_udp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_tcp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_tcp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_udp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_udp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_same_ports_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_SAME_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_same_client_ids_diff_ports_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SAME_IDS_DIFF_PORTS_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_master_udp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_slave_udp_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_SLAVE_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + # copy starter scripts into builddir + set(TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + set(TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER ${TEST_SUBSCRIBE_NOTIFY_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_SLAVE_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_UDP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} + ) + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_slave_local_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_TCP_LOCAL_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ) + set(TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SLAVE_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} + ) + +endif() + +############################################################################## +# subscribe notify one tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_SUBSCRIBE_NOTIFY_ONE_NAME subscribe_notify_one_test) + set(TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_service) + add_executable(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_service.cpp) + target_link_libraries(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config files for test into $BUILDDIR/test + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + + # copy starter scripts into builddir + set(TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + set(TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_SLAVE_STARTER} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) +endif() + +############################################################################## +# cpu-load-test +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_CPU_LOAD_NAME cpu_load_test) + + set(TEST_CPU_LOAD_SERVICE cpu_load_test_service) + add_executable(${TEST_CPU_LOAD_SERVICE} + cpu_load_tests/${TEST_CPU_LOAD_SERVICE}.cpp + cpu_load_tests/cpu_load_measurer.cpp + ) + target_link_libraries(${TEST_CPU_LOAD_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config files for test into $BUILDDIR/test + set(TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_service_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/conf/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_SERVICE_MASTER_CONFIG_FILE} + ${TEST_CPU_LOAD_SERVICE} + ) + set(TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_service_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/conf/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_SERVICE_SLAVE_CONFIG_FILE} + ${TEST_CPU_LOAD_SERVICE} + ) + + ############################################################################## + set(TEST_CPU_LOAD_CLIENT cpu_load_test_client) + add_executable(${TEST_CPU_LOAD_CLIENT} + cpu_load_tests/${TEST_CPU_LOAD_CLIENT}.cpp + cpu_load_tests/cpu_load_measurer.cpp + ) + target_link_libraries(${TEST_CPU_LOAD_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_client_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/conf/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_CLIENT_MASTER_CONFIG_FILE} + ${TEST_CPU_LOAD_CLIENT} + ) + set(TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE ${TEST_CPU_LOAD_NAME}_client_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/conf/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_CLIENT_SLAVE_CONFIG_FILE} + ${TEST_CPU_LOAD_CLIENT} + ) + + ############################################################################## + # copy starter scripts into builddir + set(TEST_CPU_LOAD_MASTER_STARTER ${TEST_CPU_LOAD_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_MASTER_STARTER} + ${TEST_CPU_LOAD_SERVICE} + ) + set(TEST_CPU_LOAD_SLAVE_STARTER ${TEST_CPU_LOAD_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/cpu_load_tests/${TEST_CPU_LOAD_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_SLAVE_STARTER} + ${TEST_CPU_LOAD_SERVICE} + ) +endif() + +############################################################################## +# initial event tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_INITIAL_EVENT_NAME initial_event_test) + set(TEST_INITIAL_EVENT_SERVICE ${TEST_INITIAL_EVENT_NAME}_service) + add_executable(${TEST_INITIAL_EVENT_SERVICE} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_service.cpp) + target_link_libraries(${TEST_INITIAL_EVENT_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_INITIAL_EVENT_CLIENT ${TEST_INITIAL_EVENT_NAME}_client) + add_executable(${TEST_INITIAL_EVENT_CLIENT} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_client.cpp) + target_link_libraries(${TEST_INITIAL_EVENT_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_INITIAL_EVENT_AVAILABILITY_CHECKER ${TEST_INITIAL_EVENT_NAME}_availability_checker) + add_executable(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_availability_checker.cpp) + target_link_libraries(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_INITIAL_EVENT_STOP_SERVICE ${TEST_INITIAL_EVENT_NAME}_stop_service) + add_executable(${TEST_INITIAL_EVENT_STOP_SERVICE} initial_event_tests/${TEST_INITIAL_EVENT_NAME}_stop_service.cpp) + target_link_libraries(${TEST_INITIAL_EVENT_STOP_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config files for test into $BUILDDIR/test + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + # Copy config files for test into $BUILDDIR/test + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + # Copy config files for test into $BUILDDIR/test + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_UDP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_UDP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_same_client_ids_same_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_MASTER_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_same_client_ids_same_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SAME_IDS_SAME_PORTS_SLAVE_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_same_client_ids_diff_ports_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_same_client_ids_diff_ports_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SAME_IDS_DIFF_PORTS_SLAVE_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_SLAVE_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + # copy starter scripts into builddir + set(TEST_INITIAL_EVENT_MASTER_STARTER ${TEST_INITIAL_EVENT_NAME}_master_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} + ${TEST_INITIAL_EVENT_SERVICE} + ) + set(TEST_INITIAL_EVENT_SLAVE_STARTER ${TEST_INITIAL_EVENT_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/initial_event_tests/${TEST_INITIAL_EVENT_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_SLAVE_STARTER} + ${TEST_INITIAL_EVENT_SERVICE} + ) +endif() + +############################################################################## +# offer tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_OFFER_NAME offer_test) + set(TEST_OFFER_SERVICE ${TEST_OFFER_NAME}_service) + add_executable(${TEST_OFFER_SERVICE} offer_tests/${TEST_OFFER_NAME}_service.cpp) + target_link_libraries(${TEST_OFFER_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_OFFER_CLIENT ${TEST_OFFER_NAME}_client) + add_executable(${TEST_OFFER_CLIENT} offer_tests/${TEST_OFFER_NAME}_client.cpp) + target_link_libraries(${TEST_OFFER_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_OFFER_SERVICE_EXTERNAL ${TEST_OFFER_NAME}_service_external) + add_executable(${TEST_OFFER_SERVICE_EXTERNAL} offer_tests/${TEST_OFFER_NAME}_service_external.cpp) + target_link_libraries(${TEST_OFFER_SERVICE_EXTERNAL} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER ${TEST_OFFER_NAME}_external_sd_msg_sender) + add_executable(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} offer_tests/${TEST_OFFER_NAME}_external_sd_msg_sender.cpp) + target_link_libraries(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # client and service for offer test big sd msg + set(TEST_OFFER_BIG_NAME offer_test_big_sd_msg) + set(TEST_OFFER_BIG_SERVICE ${TEST_OFFER_BIG_NAME}_service) + add_executable(${TEST_OFFER_BIG_SERVICE} offer_tests/${TEST_OFFER_BIG_NAME}_service.cpp) + target_link_libraries(${TEST_OFFER_BIG_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_OFFER_BIG_CLIENT ${TEST_OFFER_BIG_NAME}_client) + add_executable(${TEST_OFFER_BIG_CLIENT} offer_tests/${TEST_OFFER_BIG_NAME}_client.cpp) + target_link_libraries(${TEST_OFFER_BIG_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # copy starter scripts into builddir + set(TEST_OFFER_LOCAL_STARTER ${TEST_OFFER_NAME}_local_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_LOCAL_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_LOCAL_STARTER} + ${TEST_OFFER_SERVICE} + ) + + # Copy config file for local test into $BUILDDIR/test + set(TEST_OFFER_LOCAL_CONFIG_FILE ${TEST_OFFER_NAME}_local.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_LOCAL_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_LOCAL_CONFIG_FILE} + ${TEST_OFFER_SERVICE} + ) + + # generate and copy json files into builddir for external test + set(TEST_OFFER_SLAVE_CONFIG_FILE ${TEST_OFFER_NAME}_external_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_SLAVE_CONFIG_FILE} + ${TEST_OFFER_SERVICE} + ) + + set(TEST_OFFER_MASTER_CONFIG_FILE ${TEST_OFFER_NAME}_external_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_MASTER_CONFIG_FILE} + ${TEST_OFFER_SERVICE} + ) + + # generate and copy json files into builddir for big SD message test + set(TEST_OFFER_BIG_SLAVE_CONFIG_FILE ${TEST_OFFER_BIG_NAME}_slave.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_SLAVE_CONFIG_FILE} + ${TEST_OFFER_BIG_SERVICE} + ) + + set(TEST_OFFER_BIG_MASTER_CONFIG_FILE ${TEST_OFFER_BIG_NAME}_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_BIG_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_MASTER_CONFIG_FILE} + ${TEST_OFFER_BIG_SERVICE} + ) + + # Copy starter scripts for external test to $BUILDDIR/test + set(TEST_OFFER_EXTERNAL_MASTER_STARTER ${TEST_OFFER_NAME}_external_master_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_EXTERNAL_MASTER_STARTER}.in + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_EXTERNAL_MASTER_STARTER} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_EXTERNAL_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_EXTERNAL_MASTER_STARTER} + ${TEST_OFFER_SERVICE} + ) + set(TEST_OFFER_EXTERNAL_SLAVE_STARTER ${TEST_OFFER_NAME}_external_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_EXTERNAL_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_EXTERNAL_SLAVE_STARTER} + ${TEST_OFFER_SERVICE} + ) + + # Copy starter scripts for external test to $BUILDDIR/test + set(TEST_OFFER_BIG_MASTER_STARTER ${TEST_OFFER_BIG_NAME}_master_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/offer_tests/conf/${TEST_OFFER_BIG_MASTER_STARTER}.in + ${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_MASTER_STARTER} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_MASTER_STARTER} + ${TEST_OFFER_BIG_SERVICE} + ) + # Copy starter scripts for external test to $BUILDDIR/test + set(TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER ${TEST_OFFER_BIG_NAME}_slave_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offer_tests/${TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_EXTERNAL_SLAVE_STARTER} + ${TEST_OFFER_BIG_SERVICE} + ) +endif() + +############################################################################## +# offered services info tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_OFFERED_SERVICES_INFO_NAME offered_services_info_test) + set(TEST_OFFERED_SERVICES_INFO_SERVICE ${TEST_OFFERED_SERVICES_INFO_NAME}_service) + add_executable(${TEST_OFFERED_SERVICES_INFO_SERVICE} offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_NAME}_service.cpp) + target_link_libraries(${TEST_OFFERED_SERVICES_INFO_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_OFFERED_SERVICES_INFO_CLIENT ${TEST_OFFERED_SERVICES_INFO_NAME}_client) + add_executable(${TEST_OFFERED_SERVICES_INFO_CLIENT} offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_NAME}_client.cpp) + target_link_libraries(${TEST_OFFERED_SERVICES_INFO_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # copy starter scripts into builddir + set(TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER ${TEST_OFFERED_SERVICES_INFO_NAME}_local_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER} + ${TEST_OFFERED_SERVICES_INFO_SERVICE} + ) + + # Copy config file for local test into $BUILDDIR/test + set(TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE ${TEST_OFFERED_SERVICES_INFO_NAME}_local.json) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE} + ${TEST_OFFERED_SERVICES_INFO_SERVICE} + ) +endif() + +############################################################################## +# pending subscription tests tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_PENDING_SUBSCRIPTION_NAME pending_subscription_test) + set(TEST_PENDING_SUBSCRIPTION_SERVICE ${TEST_PENDING_SUBSCRIPTION_NAME}_service) + add_executable(${TEST_PENDING_SUBSCRIPTION_SERVICE} pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_NAME}_service.cpp) + target_link_libraries(${TEST_PENDING_SUBSCRIPTION_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + file(GLOB sd_sources + "../../implementation/service_discovery/src/*entry*.cpp" + "../../implementation/service_discovery/src/*option*.cpp" + "../../implementation/service_discovery/src/*message*.cpp" + ) + set(TEST_PENDING_SUBSCRIPTION_CLIENT ${TEST_PENDING_SUBSCRIPTION_NAME}_sd_msg_sender) + add_executable(${TEST_PENDING_SUBSCRIPTION_CLIENT} + pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_NAME}_sd_msg_sender.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp + ${sd_sources} + ) + + target_link_libraries(${TEST_PENDING_SUBSCRIPTION_CLIENT} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-sd + ) + + # copy starter scripts into builddir + set(TEST_PENDING_SUBSCRIPTION_MASTER_STARTER ${TEST_PENDING_SUBSCRIPTION_NAME}_master_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/conf/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER}.in + ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} + ${TEST_PENDING_SUBSCRIPTION_SERVICE} + ) + + # Copy config file for local test into $BUILDDIR/test + set(TEST_PENDING_SUBSCRIPTION_CONFIG_FILE ${TEST_PENDING_SUBSCRIPTION_NAME}_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/conf/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/pending_subscription_tests/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_CONFIG_FILE} + ${TEST_PENDING_SUBSCRIPTION_SERVICE} + ) +endif() + +############################################################################## +# malicious data tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_MALICIOUS_DATA_NAME malicious_data_test) + set(TEST_MALICIOUS_DATA_SERVICE ${TEST_MALICIOUS_DATA_NAME}_service) + add_executable(${TEST_MALICIOUS_DATA_SERVICE} malicious_data_tests/${TEST_MALICIOUS_DATA_NAME}_service.cpp) + target_link_libraries(${TEST_MALICIOUS_DATA_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + file(GLOB sd_sources + "../../implementation/service_discovery/src/*entry*.cpp" + "../../implementation/service_discovery/src/*option*.cpp" + "../../implementation/service_discovery/src/*message*.cpp" + ) + set(TEST_MALICIOUS_DATA_CLIENT ${TEST_MALICIOUS_DATA_NAME}_msg_sender) + add_executable(${TEST_MALICIOUS_DATA_CLIENT} + malicious_data_tests/${TEST_MALICIOUS_DATA_CLIENT}.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp + ${sd_sources} + ) + + target_link_libraries(${TEST_MALICIOUS_DATA_CLIENT} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-sd + ) + + # copy starter scripts into builddir + set(TEST_MALICIOUS_DATA_MASTER_STARTER ${TEST_MALICIOUS_DATA_NAME}_master_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/conf/${TEST_MALICIOUS_DATA_MASTER_STARTER}.in + ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/${TEST_MALICIOUS_DATA_MASTER_STARTER} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/malicious_data_tests/${TEST_MALICIOUS_DATA_MASTER_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} + ${TEST_MALICIOUS_DATA_SERVICE} + ) + + # Copy config file for local test into $BUILDDIR/test + set(TEST_MALICIOUS_DATA_CONFIG_FILE ${TEST_MALICIOUS_DATA_NAME}_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/conf/${TEST_MALICIOUS_DATA_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/${TEST_MALICIOUS_DATA_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/malicious_data_tests/${TEST_MALICIOUS_DATA_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_CONFIG_FILE} + ${TEST_MALICIOUS_DATA_SERVICE} + ) +endif() + +############################################################################## +# e2e test +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_E2E_NAME e2e_test) + set(TEST_E2E_SERVICE e2e_test_service) + set(TEST_E2E_CLIENT e2e_test_client) + + add_executable(${TEST_E2E_SERVICE} e2e_tests/${TEST_E2E_SERVICE}.cpp) + target_link_libraries(${TEST_E2E_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + add_executable(${TEST_E2E_CLIENT} + e2e_tests/${TEST_E2E_CLIENT}.cpp + ) + target_link_libraries(${TEST_E2E_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy service config file for external allow tests into $BUILDDIR/test + set(TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_E2E_NAME}_service_external.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL}.in + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_SERVICE_CONFIG_FILE_EXTERNAL} + ${TEST_E2E_SERVICE} + ) + + # Copy client config file for external allow tests into $BUILDDIR/test + set(TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_E2E_NAME}_client_external.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL}.in + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_CLIENT_CONFIG_FILE_EXTERNAL} + ${TEST_E2E_SERVICE} + ) + + # Copy bashscript to start external tests (master) into $BUILDDIR/test + set(TEST_E2E_EXTERNAL_MASTER_START_SCRIPT ${TEST_E2E_NAME}_external_master_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} + ${TEST_E2E_SERVICE} + ) + + # Copy bashscript to start external tests (slave) into $BUILDDIR/test + set(TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT ${TEST_E2E_NAME}_external_slave_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_EXTERNAL_SLAVE_START_SCRIPT} + ${TEST_E2E_SERVICE} + ) +endif() + +############################################################################## +# e2e profile 04 test +############################################################################## + +if(NOT ${TESTS_BAT} AND ${TEST_E2E_PROFILE_04}) + set(TEST_E2E_PROFILE_04_NAME e2e_profile_04_test) + set(TEST_E2E_PROFILE_04_SERVICE e2e_profile_04_test_service) + set(TEST_E2E_PROFILE_04_CLIENT e2e_profile_04_test_client) + + add_executable(${TEST_E2E_PROFILE_04_SERVICE} e2e_tests/${TEST_E2E_PROFILE_04_SERVICE}.cpp) + target_link_libraries(${TEST_E2E_PROFILE_04_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + add_executable(${TEST_E2E_PROFILE_04_CLIENT} + e2e_tests/${TEST_E2E_PROFILE_04_CLIENT}.cpp + ) + target_link_libraries(${TEST_E2E_PROFILE_04_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy service config file for external allow tests into $BUILDDIR/test + set(TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL ${TEST_E2E_PROFILE_04_NAME}_service_external.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL}.in + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_SERVICE_CONFIG_FILE_EXTERNAL} + ${TEST_E2E_PROFILE_04_SERVICE} + ) + + # Copy client config file for external allow tests into $BUILDDIR/test + set(TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL ${TEST_E2E_PROFILE_04_NAME}_client_external.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/conf/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL}.in + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_CLIENT_CONFIG_FILE_EXTERNAL} + ${TEST_E2E_PROFILE_04_SERVICE} + ) + + # Copy bashscript to start external tests (master) into $BUILDDIR/test + set(TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT ${TEST_E2E_PROFILE_04_NAME}_external_master_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} + ${TEST_E2E_PROFILE_04_SERVICE} + ) + + # Copy bashscript to start external tests (slave) into $BUILDDIR/test + set(TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT ${TEST_E2E_PROFILE_04_NAME}_external_slave_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/e2e_tests/${TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_EXTERNAL_SLAVE_START_SCRIPT} + ${TEST_E2E_PROFILE_04_SERVICE} + ) +endif() + +############################################################################## +# event tests +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_EVENT_NAME event_test) + set(TEST_EVENT_SERVICE ${TEST_EVENT_NAME}_service) + set(TEST_EVENT_CLIENT ${TEST_EVENT_NAME}_client) + + add_executable(${TEST_EVENT_SERVICE} event_tests/${TEST_EVENT_SERVICE}.cpp) + target_link_libraries(${TEST_EVENT_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + add_executable(${TEST_EVENT_CLIENT} + event_tests/${TEST_EVENT_CLIENT}.cpp + ) + target_link_libraries(${TEST_EVENT_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + # Copy service config file for external allow tests into $BUILDDIR/test + set(TEST_EVENT_SLAVE_TCP_CONFIG_FILE ${TEST_EVENT_NAME}_slave_tcp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/event_tests/conf/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_SLAVE_TCP_CONFIG_FILE} + ${TEST_EVENT_SERVICE} + ) + + set(TEST_EVENT_SLAVE_UDP_CONFIG_FILE ${TEST_EVENT_NAME}_slave_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/event_tests/conf/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_SLAVE_UDP_CONFIG_FILE} + ${TEST_EVENT_SERVICE} + ) + + set(TEST_EVENT_MASTER_CONFIG_FILE ${TEST_EVENT_NAME}_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/event_tests/conf/${TEST_EVENT_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_CONFIG_FILE} + ${TEST_EVENT_CLIENT} + ) + + # Copy bashscript to start test (master) into $BUILDDIR/test + set(TEST_EVENT_MASTER_START_SCRIPT ${TEST_EVENT_NAME}_master_starter.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} + ${TEST_EVENT_SERVICE} + ) + + # Copy bashscript to start external tests (slave) into $BUILDDIR/test + set(TEST_EVENT_SLAVE_START_SCRIPT ${TEST_EVENT_NAME}_slave_starter.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/event_tests/${TEST_EVENT_SLAVE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_SLAVE_START_SCRIPT} + ${TEST_EVENT_CLIENT} + ) + +endif() + +############################################################################## +# npdu-test +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_NPDU_NAME npdu_test) + + set(TEST_NPDU_DAEMON npdu_test_rmd) + set(TEST_NPDU_DAEMON_CLIENT ${TEST_NPDU_DAEMON}_client_side) + add_executable(${TEST_NPDU_DAEMON_CLIENT} npdu_tests/${TEST_NPDU_DAEMON}.cpp) + set_target_properties(${TEST_NPDU_DAEMON_CLIENT} PROPERTIES COMPILE_FLAGS -DRMD_CLIENT_SIDE) + target_link_libraries(${TEST_NPDU_DAEMON_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_DAEMON_SERVICE ${TEST_NPDU_DAEMON}_service_side) + add_executable(${TEST_NPDU_DAEMON_SERVICE} npdu_tests/${TEST_NPDU_DAEMON}.cpp) + set_target_properties(${TEST_NPDU_DAEMON_SERVICE} PROPERTIES COMPILE_FLAGS -DRMD_SERVICE_SIDE) + target_link_libraries(${TEST_NPDU_DAEMON_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + ############################################################################## + + set(TEST_NPDU_SERVICE npdu_test_service) + + set(TEST_NPDU_SERVICE_ONE npdu_test_service_1) + add_executable(${TEST_NPDU_SERVICE_ONE} npdu_tests/${TEST_NPDU_SERVICE}.cpp) + set_target_properties(${TEST_NPDU_SERVICE_ONE} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=0) + target_link_libraries(${TEST_NPDU_SERVICE_ONE} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_SERVICE_TWO npdu_test_service_2) + add_executable(${TEST_NPDU_SERVICE_TWO} npdu_tests/${TEST_NPDU_SERVICE}.cpp) + set_target_properties(${TEST_NPDU_SERVICE_TWO} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=1) + target_link_libraries(${TEST_NPDU_SERVICE_TWO} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_SERVICE_THREE npdu_test_service_3) + add_executable(${TEST_NPDU_SERVICE_THREE} npdu_tests/${TEST_NPDU_SERVICE}.cpp) + set_target_properties(${TEST_NPDU_SERVICE_THREE} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=2) + target_link_libraries(${TEST_NPDU_SERVICE_THREE} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_SERVICE_FOUR npdu_test_service_4) + add_executable(${TEST_NPDU_SERVICE_FOUR} npdu_tests/${TEST_NPDU_SERVICE}.cpp) + set_target_properties(${TEST_NPDU_SERVICE_FOUR} PROPERTIES COMPILE_FLAGS -DSERVICE_NUMBER=3) + target_link_libraries(${TEST_NPDU_SERVICE_FOUR} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config file for service w/o npdu into $BUILDDIR/test + set(TEST_NPDU_SERVICE_CONFIG_FILE ${TEST_NPDU_SERVICE}_no_npdu.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/conf/${TEST_NPDU_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_SERVICE_CONFIG_FILE} + ${TEST_NPDU_SERVICE_ONE} + ) + + # Copy bashscript to start service w/o npdu into $BUILDDIR/test + set(TEST_NPDU_SERVICE_START_SCRIPT ${TEST_NPDU_SERVICE}_no_npdu_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_SERVICE_START_SCRIPT} + ${TEST_NPDU_SERVICE_ONE} + ) + + # Copy config file for service with npdu into $BUILDDIR/test + set(TEST_NPDU_SERVICE_CONFIG_FILE ${TEST_NPDU_SERVICE}_npdu.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/conf/${TEST_NPDU_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_SERVICE_CONFIG_FILE} + ${TEST_NPDU_SERVICE_ONE} + ) + + # Copy bashscript to start service with npdu into $BUILDDIR/test + set(TEST_NPDU_SERVICE_START_SCRIPT ${TEST_NPDU_SERVICE}_npdu_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_SERVICE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_SERVICE_START_SCRIPT} + ${TEST_NPDU_SERVICE_ONE} + ) + + ############################################################################## + + set(TEST_NPDU_CLIENT npdu_test_client) + + set(TEST_NPDU_CLIENT_ONE npdu_test_client_1) + add_executable(${TEST_NPDU_CLIENT_ONE} npdu_tests/${TEST_NPDU_CLIENT}.cpp) + target_link_libraries(${TEST_NPDU_CLIENT_ONE} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_CLIENT_TWO npdu_test_client_2) + add_executable(${TEST_NPDU_CLIENT_TWO} npdu_tests/${TEST_NPDU_CLIENT}.cpp) + target_link_libraries(${TEST_NPDU_CLIENT_TWO} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_CLIENT_THREE npdu_test_client_3) + add_executable(${TEST_NPDU_CLIENT_THREE} npdu_tests/${TEST_NPDU_CLIENT}.cpp) + target_link_libraries(${TEST_NPDU_CLIENT_THREE} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_NPDU_CLIENT_FOUR npdu_test_client_4) + add_executable(${TEST_NPDU_CLIENT_FOUR} npdu_tests/${TEST_NPDU_CLIENT}.cpp) + target_link_libraries(${TEST_NPDU_CLIENT_FOUR} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-cfg + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # Copy config files for client w/o npdu into $BUILDDIR/test + set(TEST_NPDU_CLIENT_CONFIG_FILE ${TEST_NPDU_CLIENT}_no_npdu.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/conf/${TEST_NPDU_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_CLIENT_CONFIG_FILE} + ${TEST_NPDU_CLIENT_ONE} + ) + + # Copy bashscript to start client w/o npdu into $BUILDDIR/test + set(TEST_NPDU_CLIENT_START_SCRIPT ${TEST_NPDU_CLIENT}_no_npdu_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_CLIENT_START_SCRIPT} + ${TEST_NPDU_CLIENT_ONE} + ) + + # Copy config file for client with npdu into $BUILDDIR/test + set(TEST_NPDU_CLIENT_CONFIG_FILE ${TEST_NPDU_CLIENT}_npdu.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/conf/${TEST_NPDU_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_CLIENT_CONFIG_FILE} + ${TEST_NPDU_CLIENT_ONE} + ) + + # Copy bashscript to start client with npdu into $BUILDDIR/test + set(TEST_NPDU_CLIENT_START_SCRIPT ${TEST_NPDU_CLIENT}_npdu_start.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_CLIENT_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_CLIENT_START_SCRIPT} + ${TEST_NPDU_CLIENT_ONE} + ) + + ############################################################################## + + set(TEST_NPDU_STARTER ${TEST_NPDU_NAME}_starter.sh) + copy_to_builddir(${NETWORK_TEST_SRC_DIR}/npdu_tests/${TEST_NPDU_STARTER} + ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_STARTER} + ${TEST_NPDU_DAEMON_CLIENT} + ) +endif() + +############################################################################## +# someip tp tests +############################################################################## + +if(NOT ${TESTS_BAT}) + set(TEST_SOMEIPTP_NAME someip_tp_test) + set(TEST_SOMEIPTP_SERVICE ${TEST_SOMEIPTP_NAME}_service) + + add_executable(${TEST_SOMEIPTP_SERVICE} someip_tp_tests/${TEST_SOMEIPTP_SERVICE}.cpp) + target_link_libraries(${TEST_SOMEIPTP_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + file(GLOB sd_sources + "../../implementation/service_discovery/src/*entry*.cpp" + "../../implementation/service_discovery/src/*option*.cpp" + "../../implementation/service_discovery/src/*message*.cpp" + ) + set(TEST_SOMEIPTP_CLIENT ${TEST_SOMEIPTP_NAME}_msg_sender) + add_executable(${TEST_SOMEIPTP_CLIENT} + someip_tp_tests/${TEST_SOMEIPTP_CLIENT}.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/deserializer.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/message_impl.cpp + ${PROJECT_SOURCE_DIR}/implementation/message/src/payload_impl.cpp + ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp.cpp + ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp_reassembler.cpp + ${PROJECT_SOURCE_DIR}/implementation/endpoints/src/tp_message.cpp + ${sd_sources} + ) + + target_link_libraries(${TEST_SOMEIPTP_CLIENT} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ${VSOMEIP_NAME} + ${VSOMEIP_NAME}-sd + ) + + # Copy service config file for external allow tests into $BUILDDIR/test + set(TEST_SOMEIPTP_MASTER_CONFIG_FILE ${TEST_SOMEIPTP_NAME}_master.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/conf/${TEST_SOMEIPTP_MASTER_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_CONFIG_FILE} + ${TEST_SOMEIPTP_CLIENT} + ) + + # Copy bashscript to start test (master) into $BUILDDIR/test + set(TEST_SOMEIPTP_MASTER_START_SCRIPT ${TEST_SOMEIPTP_NAME}_master_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/conf/${TEST_SOMEIPTP_MASTER_START_SCRIPT}.in + ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/${TEST_SOMEIPTP_MASTER_START_SCRIPT} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/someip_tp_tests/${TEST_SOMEIPTP_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} + ${TEST_SOMEIPTP_SERVICE} + ) +endif() + +############################################################################## +# second IP address tests +############################################################################## + +if(NOT ${TESTS_BAT} AND ${TEST_SECOND_ADDRESS}) + set(TEST_SECOND_ADDRESS_NAME second_address_test) + set(TEST_SECOND_ADDRESS_SERVICE ${TEST_SECOND_ADDRESS_NAME}_service) + set(TEST_SECOND_ADDRESS_CLIENT ${TEST_SECOND_ADDRESS_NAME}_client) + + add_executable(${TEST_SECOND_ADDRESS_SERVICE} + second_address_tests/${TEST_SECOND_ADDRESS_SERVICE}.cpp + ) + target_link_libraries(${TEST_SECOND_ADDRESS_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + add_executable(${TEST_SECOND_ADDRESS_CLIENT} + second_address_tests/${TEST_SECOND_ADDRESS_CLIENT}.cpp + ) + target_link_libraries(${TEST_SECOND_ADDRESS_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_master_service_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_SERVICE_UDP_CONFIG_FILE} + ${TEST_SECOND_ADDRESS_SERVICE} + ) + + set(TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_slave_client.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_SLAVE_CLIENT_CONFIG_FILE} + ${TEST_SECOND_ADDRESS_CLIENT} + ) + + set(TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_master_client.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_CLIENT_CONFIG_FILE} + ${TEST_SECOND_ADDRESS_CLIENT} + ) + + set(TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE ${TEST_SECOND_ADDRESS_NAME}_slave_service_udp.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_SLAVE_SERVICE_UDP_CONFIG_FILE} + ${TEST_SECOND_ADDRESS_SERVICE} + ) + + set(TEST_SECOND_ADDRESS_MASTER_START_SCRIPT ${TEST_SECOND_ADDRESS_NAME}_master_starter.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} + ${TEST_SECOND_ADDRESS_SERVICE} + ) + + set(TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT ${TEST_SECOND_ADDRESS_NAME}_slave_starter.sh) + configure_file( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/conf/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT}.in + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/second_address_tests/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_SLAVE_START_SCRIPT} + ${TEST_SECOND_ADDRESS_CLIENT} + ) +endif() + +############################################################################## +# suspend resume tests +############################################################################## +if(NOT ${TESTS_BAT}) + + set(TEST_SUSPEND_RESUME_NAME suspend_resume_test) + set(TEST_SUSPEND_RESUME_SERVICE ${TEST_SUSPEND_RESUME_NAME}_service) + set(TEST_SUSPEND_RESUME_CLIENT ${TEST_SUSPEND_RESUME_NAME}_client) + + add_executable(${TEST_SUSPEND_RESUME_SERVICE} + suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE}.cpp + ) + target_link_libraries(${TEST_SUSPEND_RESUME_SERVICE} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + add_executable(${TEST_SUSPEND_RESUME_CLIENT} + suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT}.cpp + ) + target_link_libraries(${TEST_SUSPEND_RESUME_CLIENT} + ${VSOMEIP_NAME} + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE ${TEST_SUSPEND_RESUME_SERVICE}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/conf/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_SERVICE_CONFIG_FILE} + ${TEST_SUSPEND_RESUME_CLIENT} + ) + + set(TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE ${TEST_SUSPEND_RESUME_CLIENT}.json) + configure_file( + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/conf/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE}.in + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_CLIENT_CONFIG_FILE} + ${TEST_SUSPEND_RESUME_CLIENT} + ) + + set(TEST_SUSPEND_RESUME_MASTER_START_SCRIPT ${TEST_SUSPEND_RESUME_NAME}_master_starter.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} + ${TEST_SUSPEND_RESUME_CLIENT} + ) + + set(TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT ${TEST_SUSPEND_RESUME_NAME}_slave_starter.sh) + copy_to_builddir( + ${NETWORK_TEST_SRC_DIR}/suspend_resume_tests/${TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT} + ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_SLAVE_START_SCRIPT} + ${TEST_SUSPEND_RESUME_CLIENT} + ) + +endif() + +############################################################################## +# Add for every test a dependency to gtest +############################################################################## + +if(NOT ${TESTS_BAT}) + add_dependencies(${TEST_CONFIGURATION} gtest) + add_dependencies(${TEST_APPLICATION} gtest) + add_dependencies(${TEST_APPLICATION_SINGLE_PROCESS_NAME} gtest) + add_dependencies(${TEST_APPLICATION_AVAILABILITY_NAME} gtest) + add_dependencies(${TEST_MAGIC_COOKIES_CLIENT} gtest) + add_dependencies(${TEST_MAGIC_COOKIES_SERVICE} gtest) + add_dependencies(${TEST_HEADER_FACTORY} gtest) + add_dependencies(${TEST_HEADER_FACTORY_CLIENT} gtest) + add_dependencies(${TEST_HEADER_FACTORY_SERVICE} gtest) + add_dependencies(${TEST_LOCAL_ROUTING_SERVICE} gtest) + add_dependencies(${TEST_LOCAL_ROUTING_CLIENT} gtest) + add_dependencies(${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE} gtest) + add_dependencies(${TEST_PAYLOAD_SERVICE} gtest) + add_dependencies(${TEST_PAYLOAD_CLIENT} gtest) + add_dependencies(${TEST_BIG_PAYLOAD_SERVICE} gtest) + add_dependencies(${TEST_BIG_PAYLOAD_CLIENT} gtest) + add_dependencies(${TEST_CLIENT_ID_SERVICE} gtest) + add_dependencies(${TEST_CLIENT_ID_UTILITY} gtest) + add_dependencies(${TEST_DEBOUNCE_CLIENT} gtest) + add_dependencies(${TEST_DEBOUNCE_SERVICE} gtest) + add_dependencies(${TEST_SUBSCRIBE_NOTIFY_SERVICE} gtest) + add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE} gtest) + add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT} gtest) + add_dependencies(${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} gtest) + add_dependencies(${TEST_CPU_LOAD_SERVICE} gtest) + add_dependencies(${TEST_CPU_LOAD_CLIENT} gtest) + add_dependencies(${TEST_INITIAL_EVENT_SERVICE} gtest) + add_dependencies(${TEST_INITIAL_EVENT_CLIENT} gtest) + add_dependencies(${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER} gtest) + add_dependencies(${TEST_INITIAL_EVENT_STOP_SERVICE} gtest) + add_dependencies(${TEST_OFFER_SERVICE} gtest) + add_dependencies(${TEST_OFFER_CLIENT} gtest) + add_dependencies(${TEST_OFFER_SERVICE_EXTERNAL} gtest) + add_dependencies(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} gtest) + add_dependencies(${TEST_OFFERED_SERVICES_INFO_CLIENT} gtest) + add_dependencies(${TEST_OFFERED_SERVICES_INFO_SERVICE} gtest) + add_dependencies(${TEST_PENDING_SUBSCRIPTION_SERVICE} gtest) + add_dependencies(${TEST_PENDING_SUBSCRIPTION_CLIENT} gtest) + add_dependencies(${TEST_MALICIOUS_DATA_SERVICE} gtest) + add_dependencies(${TEST_MALICIOUS_DATA_CLIENT} gtest) + if (${TEST_SECURITY}) + add_dependencies(${TEST_SECURITY_SERVICE} gtest) + add_dependencies(${TEST_SECURITY_CLIENT} gtest) + endif() + add_dependencies(${TEST_E2E_SERVICE} gtest) + add_dependencies(${TEST_E2E_CLIENT} gtest) + if (${TEST_E2E_PROFILE_04}) + add_dependencies(${TEST_E2E_PROFILE_04_SERVICE} gtest) + add_dependencies(${TEST_E2E_PROFILE_04_CLIENT} gtest) + endif() + add_dependencies(${TEST_EVENT_SERVICE} gtest) + add_dependencies(${TEST_EVENT_CLIENT} gtest) + add_dependencies(${TEST_NPDU_SERVICE_ONE} gtest) + add_dependencies(${TEST_NPDU_SERVICE_TWO} gtest) + add_dependencies(${TEST_NPDU_SERVICE_THREE} gtest) + add_dependencies(${TEST_NPDU_SERVICE_FOUR} gtest) + add_dependencies(${TEST_NPDU_CLIENT_ONE} gtest) + add_dependencies(${TEST_NPDU_CLIENT_TWO} gtest) + add_dependencies(${TEST_NPDU_CLIENT_THREE} gtest) + add_dependencies(${TEST_NPDU_CLIENT_FOUR} gtest) + add_dependencies(${TEST_NPDU_DAEMON_CLIENT} gtest) + add_dependencies(${TEST_NPDU_DAEMON_SERVICE} gtest) + add_dependencies(${TEST_SOMEIPTP_CLIENT} gtest) + add_dependencies(${TEST_SOMEIPTP_SERVICE} gtest) + if(${TEST_SECOND_ADDRESS}) + add_dependencies(${TEST_SECOND_ADDRESS_CLIENT} gtest) + add_dependencies(${TEST_SECOND_ADDRESS_SERVICE} gtest) + endif() + add_dependencies(${TEST_SUSPEND_RESUME_CLIENT} gtest) + add_dependencies(${TEST_SUSPEND_RESUME_SERVICE} gtest) +else() + add_dependencies(${TEST_LOCAL_ROUTING_SERVICE} gtest) + add_dependencies(${TEST_LOCAL_ROUTING_CLIENT} gtest) +endif() + +############################################################################## +# Add tests to the target build_network_tests +############################################################################## + +if(NOT ${TESTS_BAT}) + add_dependencies(build_network_tests ${TEST_CONFIGURATION}) + add_dependencies(build_network_tests ${TEST_APPLICATION}) + add_dependencies(build_network_tests ${TEST_APPLICATION_SINGLE_PROCESS_NAME}) + add_dependencies(build_network_tests ${TEST_APPLICATION_AVAILABILITY_NAME}) + add_dependencies(build_network_tests ${TEST_MAGIC_COOKIES_CLIENT}) + add_dependencies(build_network_tests ${TEST_MAGIC_COOKIES_SERVICE}) + add_dependencies(build_network_tests ${TEST_HEADER_FACTORY}) + add_dependencies(build_network_tests ${TEST_HEADER_FACTORY_CLIENT}) + add_dependencies(build_network_tests ${TEST_HEADER_FACTORY_SERVICE}) + add_dependencies(build_network_tests ${TEST_LOCAL_ROUTING_SERVICE}) + add_dependencies(build_network_tests ${TEST_LOCAL_ROUTING_CLIENT}) + add_dependencies(build_network_tests ${TEST_EXTERNAL_LOCAL_ROUTING_SERVICE}) + add_dependencies(build_network_tests ${TEST_PAYLOAD_SERVICE}) + add_dependencies(build_network_tests ${TEST_PAYLOAD_CLIENT}) + add_dependencies(build_network_tests ${TEST_BIG_PAYLOAD_SERVICE}) + add_dependencies(build_network_tests ${TEST_BIG_PAYLOAD_CLIENT}) + add_dependencies(build_network_tests ${TEST_CLIENT_ID_SERVICE}) + add_dependencies(build_network_tests ${TEST_CLIENT_ID_UTILITY}) + add_dependencies(build_network_tests ${TEST_DEBOUNCE_CLIENT}) + add_dependencies(build_network_tests ${TEST_DEBOUNCE_SERVICE}) + add_dependencies(build_network_tests ${TEST_SUBSCRIBE_NOTIFY_SERVICE}) + add_dependencies(build_network_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_SERVICE}) + add_dependencies(build_network_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_CLIENT}) + add_dependencies(build_network_tests ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE}) + add_dependencies(build_network_tests ${TEST_CPU_LOAD_SERVICE}) + add_dependencies(build_network_tests ${TEST_CPU_LOAD_CLIENT}) + add_dependencies(build_network_tests ${TEST_INITIAL_EVENT_SERVICE}) + add_dependencies(build_network_tests ${TEST_INITIAL_EVENT_CLIENT}) + add_dependencies(build_network_tests ${TEST_INITIAL_EVENT_AVAILABILITY_CHECKER}) + add_dependencies(build_network_tests ${TEST_INITIAL_EVENT_STOP_SERVICE}) + add_dependencies(build_network_tests ${TEST_OFFER_SERVICE}) + add_dependencies(build_network_tests ${TEST_OFFER_CLIENT}) + add_dependencies(build_network_tests ${TEST_OFFER_SERVICE_EXTERNAL}) + add_dependencies(build_network_tests ${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER}) + add_dependencies(build_network_tests ${TEST_OFFER_BIG_SERVICE}) + add_dependencies(build_network_tests ${TEST_OFFER_BIG_CLIENT}) + add_dependencies(build_network_tests ${TEST_RESTART_ROUTING_SERVICE}) + add_dependencies(build_network_tests ${TEST_RESTART_ROUTING_CLIENT}) + if (${TEST_SECURITY}) + add_dependencies(build_network_tests ${TEST_SECURITY_SERVICE}) + add_dependencies(build_network_tests ${TEST_SECURITY_CLIENT}) + endif() + add_dependencies(build_network_tests ${TEST_OFFERED_SERVICES_INFO_CLIENT}) + add_dependencies(build_network_tests ${TEST_OFFERED_SERVICES_INFO_SERVICE}) + add_dependencies(build_network_tests ${TEST_PENDING_SUBSCRIPTION_SERVICE}) + add_dependencies(build_network_tests ${TEST_PENDING_SUBSCRIPTION_CLIENT}) + add_dependencies(build_network_tests ${TEST_MALICIOUS_DATA_SERVICE}) + add_dependencies(build_network_tests ${TEST_MALICIOUS_DATA_CLIENT}) + add_dependencies(build_network_tests ${TEST_E2E_SERVICE}) + add_dependencies(build_network_tests ${TEST_E2E_CLIENT}) + if (${TEST_E2E_PROFILE_04}) + add_dependencies(build_network_tests ${TEST_E2E_PROFILE_04_SERVICE}) + add_dependencies(build_network_tests ${TEST_E2E_PROFILE_04_CLIENT}) + endif() + add_dependencies(build_network_tests ${TEST_EVENT_SERVICE}) + add_dependencies(build_network_tests ${TEST_EVENT_CLIENT}) + add_dependencies(build_network_tests ${TEST_NPDU_SERVICE_ONE}) + add_dependencies(build_network_tests ${TEST_NPDU_SERVICE_TWO}) + add_dependencies(build_network_tests ${TEST_NPDU_SERVICE_THREE}) + add_dependencies(build_network_tests ${TEST_NPDU_SERVICE_FOUR}) + add_dependencies(build_network_tests ${TEST_NPDU_CLIENT_ONE}) + add_dependencies(build_network_tests ${TEST_NPDU_CLIENT_TWO}) + add_dependencies(build_network_tests ${TEST_NPDU_CLIENT_THREE}) + add_dependencies(build_network_tests ${TEST_NPDU_CLIENT_FOUR}) + add_dependencies(build_network_tests ${TEST_NPDU_DAEMON_CLIENT}) + add_dependencies(build_network_tests ${TEST_NPDU_DAEMON_SERVICE}) + add_dependencies(build_network_tests ${TEST_SOMEIPTP_CLIENT}) + add_dependencies(build_network_tests ${TEST_SOMEIPTP_SERVICE}) + if(${TEST_SECOND_ADDRESS}) + add_dependencies(build_network_tests ${TEST_SECOND_ADDRESS_CLIENT}) + add_dependencies(build_network_tests ${TEST_SECOND_ADDRESS_SERVICE}) + endif() + add_dependencies(build_network_tests ${TEST_SUSPEND_RESUME_CLIENT}) + add_dependencies(build_network_tests ${TEST_SUSPEND_RESUME_SERVICE}) +else() + add_dependencies(build_network_tests ${TEST_LOCAL_ROUTING_SERVICE}) + add_dependencies(build_network_tests ${TEST_LOCAL_ROUTING_CLIENT}) +endif() + +# some tests require the routingmanagerd +add_dependencies(build_network_tests routingmanagerd) + +############################################################################## +# Add tests +############################################################################## + +if(NOT ${TESTS_BAT}) + add_test(NAME ${TEST_CONFIGURATION} + COMMAND ${TEST_CONFIGURATION} + ) + + # application test + add_test(NAME ${TEST_APPLICATION} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_STARTER} + ) + set_tests_properties(${TEST_APPLICATION} PROPERTIES TIMEOUT 80) + add_test(NAME ${TEST_APPLICATION_SINGLE_PROCESS_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_SINGLE_PROCESS_STARTER} + ) + set_tests_properties(${TEST_APPLICATION_SINGLE_PROCESS_NAME} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_APPLICATION_AVAILABILITY_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_APPLICATION_AVAILABILITY_STARTER} + ) + set_tests_properties(${TEST_APPLICATION_AVAILABILITY_NAME} PROPERTIES TIMEOUT 120) + + # magic cookies test + add_test(NAME ${TEST_MAGIC_COOKIES_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MAGIC_COOKIES_STARTER} + ) + set_tests_properties(${TEST_MAGIC_COOKIES_NAME} PROPERTIES TIMEOUT 250) + + # Header/Factory tets + add_test(NAME ${TEST_HEADER_FACTORY_NAME} COMMAND ${TEST_HEADER_FACTORY}) + add_test(NAME ${TEST_HEADER_FACTORY_NAME}_send_receive + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_HEADER_FACTORY_STARTER} + ) + + # Routing tests + add_test(NAME ${TEST_LOCAL_ROUTING_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_STARTER} + ) + + add_test(NAME ${TEST_EXTERNAL_LOCAL_ROUTING_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_ROUTING_STARTER} + ) + set_tests_properties(${TEST_EXTERNAL_LOCAL_ROUTING_NAME} PROPERTIES TIMEOUT 120) + + # Payload tests + add_test(NAME ${TEST_LOCAL_PAYLOAD_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_STARTER} + ) + add_test(NAME ${TEST_LOCAL_PAYLOAD_HUGE_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_PAYLOAD_HUGE_STARTER} + ) + set_tests_properties(${TEST_LOCAL_PAYLOAD_HUGE_NAME} PROPERTIES TIMEOUT 960) + add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_STARTER} + ) + add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_STARTER} + ) + set_tests_properties(${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} PROPERTIES TIMEOUT 480) + add_test(NAME ${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_LOCAL_AND_EXTERNAL_STARTER} + ) + set_tests_properties(${TEST_EXTERNAL_LOCAL_PAYLOAD_CLIENT_EXTERNAL_NAME} PROPERTIES TIMEOUT 480) + + # big payload tests + add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} + ) + set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} RANDOM + ) + set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} LIMITED + ) + set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL + ) + set_tests_properties(${TEST_LOCAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} + ) + set_tests_properties(${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_RANDOM} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} RANDOM + ) + set_tests_properties(${TEST_LOCAL_TCP_TCP_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_LIMITED} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} LIMITED + ) + set_tests_properties(${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_QUEUE_LIMITED} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_TCP_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL + ) + set_tests_properties(${TEST_LOCAL_TCP_BIG_PAYLOAD_NAME_QUEUE_LIMITED} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} RANDOM + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_RANDOM} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} LIMITED + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} LIMITEDGENERAL + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_LIMITED_GENERAL} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDGENERAL + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_GENERAL} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} QUEUELIMITEDSPECIFIC + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_QUEUE_LIMITED_SPECIFIC} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EXTERNAL_BIG_PAYLOAD_STARTER} UDP + ) + set_tests_properties(${TEST_EXTERNAL_BIG_PAYLOAD_NAME_UDP} PROPERTIES TIMEOUT 120) + + # client id tests + add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_diff_ports PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_same_ports PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_MASTER_STARTER} ${TEST_CLIENT_ID_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_CLIENT_ID_NAME}_diff_client_ids_partial_same_ports PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_CLIENT_ID_UTILITY} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) + set_property(TEST ${TEST_CLIENT_ID_UTILITY} + APPEND PROPERTY ENVIRONMENT + "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_CONFIG_FILE}") + set_tests_properties(${TEST_CLIENT_ID_UTILITY} PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_511 + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) + set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_511 + APPEND PROPERTY ENVIRONMENT + "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_511_CONFIG_FILE}") + set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_511 PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_4095 + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) + set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_4095 + APPEND PROPERTY ENVIRONMENT + "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_4095_CONFIG_FILE}") + set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_4095 PROPERTIES TIMEOUT 600) + + add_test(NAME ${TEST_CLIENT_ID_UTILITY}_masked_127 + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) + set_property(TEST ${TEST_CLIENT_ID_UTILITY}_masked_127 + APPEND PROPERTY ENVIRONMENT + "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_127_CONFIG_FILE}") + set_tests_properties(${TEST_CLIENT_ID_UTILITY}_masked_127 PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CLIENT_ID_UTILITY}) + set_property(TEST ${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 + APPEND PROPERTY ENVIRONMENT + "VSOMEIP_CONFIGURATION=${TEST_CLIENT_ID_UTILITY_MASKED_DISCONTINUOUS_511_CONFIG_FILE}") + set_tests_properties(${TEST_CLIENT_ID_UTILITY}_discontinuous_masked_511 PROPERTIES TIMEOUT 120) + + # debounce tests + add_test(NAME ${TEST_DEBOUNCE_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_DEBOUNCE_MASTER_STARTER}) + set_tests_properties(${TEST_DEBOUNCE_UTILITY} PROPERTIES TIMEOUT 30) + + # subscribe notify tests (local communication via UDS) + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_LOCAL_TCP_CONFIG_FILE} SAME_SERVICE_ID) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp_local_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_local_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_LOCAL_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp_local_tcp PROPERTIES TIMEOUT 120) + + # subscribe_notify_tests (local communication via TCP) + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_UDP_CONFIG_FILE} SAME_SERVICE_ID) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_autoconfig_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_AUTOCONFIG_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_EVENT_TWO_EVENTGROUPS_NAME}_tcp PROPERTIES TIMEOUT 120) + + # subscribe notify one id tests + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + # cpu load tests + add_test(NAME ${TEST_CPU_LOAD_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_CPU_LOAD_MASTER_STARTER} + ) + set_tests_properties(${TEST_CPU_LOAD_NAME} PROPERTIES TIMEOUT 3000) + + # initial event tests + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_partial_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_same_service_id_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID MULTIPLE_EVENTS) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_partial_same_ports_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_partial_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_same_service_id_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SAME_SERVICEID_MASTER_CONFIG_FILE} TCP_AND_UDP SAME_SERVICE_ID MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_same_service_id_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_UDP_CONFIG_FILE} UDP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} TCP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_tcp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_both_tcp_and_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} TCP_AND_UDP MULTIPLE_EVENTS SUBSCRIBE_ONLY_ONE) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_partial_subscription_both_tcp_and_udp PROPERTIES TIMEOUT 120) + + add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp_client_subscribes_twice + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_INITIAL_EVENT_MASTER_STARTER} ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_UDP_CONFIG_FILE} UDP CLIENT_SUBSCRIBES_TWICE) + set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp_client_subscribes_twice PROPERTIES TIMEOUT 120) + + # offer tests + add_test(NAME ${TEST_OFFER_NAME}_local + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_LOCAL_STARTER}) + set_tests_properties(${TEST_OFFER_NAME}_local PROPERTIES TIMEOUT 180) + add_test(NAME ${TEST_OFFER_NAME}_external + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_EXTERNAL_MASTER_STARTER}) + set_tests_properties(${TEST_OFFER_NAME}_local PROPERTIES TIMEOUT 360) + add_test(NAME ${TEST_OFFER_BIG_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_OFFER_BIG_MASTER_STARTER}) + set_tests_properties(${TEST_OFFER_BIG_NAME} PROPERTIES TIMEOUT 360) + + # offered services info tets + add_test(NAME ${TEST_OFFERED_SERVICES_INFO_NAME}_local + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER}) + set_tests_properties(${TEST_OFFERED_SERVICES_INFO_NAME}_local PROPERTIES TIMEOUT 180) + + # Restart-Routing tests + add_test(NAME ${TEST_RESTART_ROUTING_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_RESTART_ROUTING_STARTER} + ) + if (${TEST_SECURITY}) + # Security tests + add_test(NAME ${TEST_SECURITY_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_SERVICE_LOCAL_START_SCRIPT} + ) + add_test(NAME ${TEST_SECURITY_NAME}_external_allow + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} security_test_config_client_external_allow.json --allow + ) + add_test(NAME ${TEST_SECURITY_NAME}_external_deny + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECURITY_EXTERNAL_MASTER_START_SCRIPT} security_test_config_client_external_deny.json --deny + ) + endif() + + # pending subscriptions test + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_unsubscribe + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} UNSUBSCRIBE) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_unsubscribe PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_nack + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE_NACK) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_nack PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_same_port + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_UNSUBSCRIBE_SAME_PORT) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_alternating_subscribe_unsubscribe_same_port PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_resubscribe_mixed + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_RESUBSCRIBE_MIXED) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_resubscribe_mixed PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_stopsubscribe_subscribe + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_subscribe_stopsubscribe_subscribe PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_PENDING_SUBSCRIPTION_NAME}_send_request_to_sd_port + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_PENDING_SUBSCRIPTION_MASTER_STARTER} REQUEST_TO_SD) + set_tests_properties(${TEST_PENDING_SUBSCRIPTION_NAME}_send_request_to_sd_port PROPERTIES TIMEOUT 180) + + # malicious data test + add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_events + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} MALICIOUS_EVENTS) + set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_events PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_protocol_version + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} PROTOCOL_VERSION) + set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_protocol_version PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_message_type + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} MESSAGE_TYPE) + set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_message_type PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_return_code + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} RETURN_CODE) + set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_return_code PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_MALICIOUS_DATA_NAME}_wrong_header_fields_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_MALICIOUS_DATA_MASTER_STARTER} WRONG_HEADER_FIELDS_UDP) + set_tests_properties(${TEST_MALICIOUS_DATA_NAME}_wrong_header_fields_udp PROPERTIES TIMEOUT 180) + + # npdu tests + add_test(NAME ${TEST_NPDU_NAME}_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_STARTER} UDP sync) + set_tests_properties(${TEST_NPDU_NAME}_udp PROPERTIES TIMEOUT 840) + + add_test(NAME ${TEST_NPDU_NAME}_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_NPDU_STARTER} TCP sync) + set_tests_properties(${TEST_NPDU_NAME}_tcp PROPERTIES TIMEOUT 840) + + # e2e tests + add_test(NAME ${TEST_E2E_NAME}_external + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_EXTERNAL_MASTER_START_SCRIPT} e2e_test_client_external.json) + set_tests_properties(${TEST_E2E_NAME}_external PROPERTIES TIMEOUT 180) + + if (${TEST_E2E_PROFILE_04}) + add_test(NAME ${TEST_E2E_PROFILE_04_NAME}_external + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_E2E_PROFILE_04_EXTERNAL_MASTER_START_SCRIPT} e2e_profile_04_test_client_external.json) + set_tests_properties(${TEST_E2E_PROFILE_04_NAME}_external PROPERTIES TIMEOUT 180) + endif () + + # event tests + add_test(NAME ${TEST_EVENT_NAME}_payload_fixed_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_FIXED UDP) + set_tests_properties(${TEST_EVENT_NAME}_payload_fixed_udp PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_EVENT_NAME}_payload_fixed_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_FIXED TCP) + set_tests_properties(${TEST_EVENT_NAME}_payload_fixed_tcp PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_EVENT_NAME}_payload_dynamic_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_DYNAMIC UDP) + set_tests_properties(${TEST_EVENT_NAME}_payload_dynamic_udp PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_EVENT_NAME}_payload_dynamic_tcp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_EVENT_MASTER_START_SCRIPT} PAYLOAD_DYNAMIC TCP) + set_tests_properties(${TEST_EVENT_NAME}_payload_dynamic_tcp PROPERTIES TIMEOUT 180) + + # SOME/IP-TP tests + add_test(NAME ${TEST_SOMEIPTP_NAME}_in_sequence + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} IN_SEQUENCE) + set_tests_properties(${TEST_SOMEIPTP_NAME}_in_sequence PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_SOMEIPTP_NAME}_mixed + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} MIXED) + set_tests_properties(${TEST_SOMEIPTP_NAME}_mixed PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_SOMEIPTP_NAME}_incomplete + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} INCOMPLETE) + set_tests_properties(${TEST_SOMEIPTP_NAME}_incomplete PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_SOMEIPTP_NAME}_duplicate + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} DUPLICATE) + set_tests_properties(${TEST_SOMEIPTP_NAME}_duplicate PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_SOMEIPTP_NAME}_overlap + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} OVERLAP) + set_tests_properties(${TEST_SOMEIPTP_NAME}_overlap PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_SOMEIPTP_NAME}_overlap_front_back + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SOMEIPTP_MASTER_START_SCRIPT} OVERLAP_FRONT_BACK) + set_tests_properties(${TEST_SOMEIPTP_NAME}_overlap_front_back PROPERTIES TIMEOUT 180) + + if(${TEST_SECOND_ADDRESS}) + add_test(NAME ${TEST_SECOND_ADDRESS_NAME}_second_ip_address_service_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} SERVICE UDP + ) + set_tests_properties(${TEST_SECOND_ADDRESS_NAME}_second_ip_address_service_udp PROPERTIES TIMEOUT 180) + + add_test(NAME ${TEST_SECOND_ADDRESS_NAME}_second_ip_address_client_udp + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SECOND_ADDRESS_MASTER_START_SCRIPT} CLIENT UDP + ) + set_tests_properties(${TEST_SECOND_ADDRESS_NAME}_second_ip_address_client_udp PROPERTIES TIMEOUT 180) + endif() + + # suspend resume test + add_test(NAME ${TEST_SUSPEND_RESUME_NAME}_initial + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_SUSPEND_RESUME_MASTER_START_SCRIPT} SERVICE + ) + +else() + # Routing tests + add_test(NAME ${TEST_LOCAL_ROUTING_NAME} + COMMAND ${NETWORK_TEST_BIN_DIR}/${TEST_LOCAL_ROUTING_STARTER} + ) +endif() diff --git a/test/network_tests/application_tests/application_test.cpp b/test/network_tests/application_tests/application_test.cpp new file mode 100644 index 0000000..c7ad4f8 --- /dev/null +++ b/test/network_tests/application_tests/application_test.cpp @@ -0,0 +1,479 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include + +#include + +#include + +#include "someip_test_globals.hpp" + +using namespace vsomeip; + +class someip_application_test: public ::testing::Test { +public: + someip_application_test() : + registered_(false) { + + } +protected: + void SetUp() { + app_ = runtime::get()->create_application("application_test"); + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + + app_->register_state_handler( + std::bind(&someip_application_test::on_state, this, + std::placeholders::_1)); + } + + void on_state(vsomeip::state_type_e _state) { + registered_ = (_state == vsomeip::state_type_e::ST_REGISTERED); + } + + bool registered_; + std::shared_ptr app_; +}; + +/** + * @test Start and stop application + */ +TEST_F(someip_application_test, start_stop_application) +{ + std::promise its_promise; + std::thread t([&](){ + its_promise.set_value(true); + app_->start(); + }); + EXPECT_TRUE(its_promise.get_future().get()); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + app_->stop(); + t.join(); +} + +/** + * @test Start and stop application multiple times + */ +TEST_F(someip_application_test, start_stop_application_multiple) +{ + for (int i = 0; i < 10; ++i) { + std::promise its_promise; + std::thread t([&]() { + its_promise.set_value(true); + app_->start(); + }); + EXPECT_TRUE(its_promise.get_future().get()); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + app_->stop(); + t.join(); + } +} + +/** + * @test Start and stop application multiple times and offer a service + */ +TEST_F(someip_application_test, start_stop_application_multiple_offer_service) +{ + for (int i = 0; i < 10; ++i) { + std::promise its_promise; + std::thread t([&]() { + its_promise.set_value(true); + app_->start(); + }); + EXPECT_TRUE(its_promise.get_future().get()); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + app_->stop(); + t.join(); + } +} + +/** + * @test Try to start an already running application again + */ +TEST_F(someip_application_test, restart_without_stopping) +{ + std::promise its_promise; + std::thread t([&]() { + its_promise.set_value(true); + app_->start(); + + }); + EXPECT_TRUE(its_promise.get_future().get()); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + VSOMEIP_WARNING << "An error message should appear now"; + // should print error + app_->start(); + app_->stop(); + t.join(); +} + +/** + * @test Try to stop a running application twice + */ +TEST_F(someip_application_test, stop_application_twice) +{ + std::promise its_promise; + std::thread t([&]() { + its_promise.set_value(true); + app_->start(); + + }); + EXPECT_TRUE(its_promise.get_future().get()); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + app_->stop(); + t.join(); + app_->stop(); +} + +/** + * @test Checks whether watchdog handler is invoked (regularly) also after restarting. + */ +TEST_F(someip_application_test, watchdog_handler) +{ + std::atomic cb_count(0); + auto wd_handler = [&] () { + ++cb_count; + }; + + app_->set_watchdog_handler(std::cref(wd_handler), std::chrono::seconds(1)); + + std::promise its_promise; + std::thread t([&]() { + its_promise.set_value(true); + app_->start(); + }); + EXPECT_TRUE(its_promise.get_future().get()); + + // wait till watchdog handler has been invoked once + while (0 == cb_count.load()) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + ASSERT_EQ(1, cb_count.load()); + + // clear handler (must not be called again) + app_->set_watchdog_handler(nullptr, std::chrono::seconds::zero()); + + // wait doubled interval (used previously).. + std::this_thread::sleep_for(std::chrono::seconds(2)); + // .. to ensure it was not called again + ASSERT_EQ(1, cb_count.load()); + + // enable handler again + app_->set_watchdog_handler(std::cref(wd_handler), std::chrono::seconds(1)); + + // wait till watchdog handler has been invoked again (2nd time) + while (1 == cb_count.load()) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + app_->stop(); + t.join(); + + // wait doubled interval (used previously).. + std::this_thread::sleep_for(std::chrono::seconds(2)); + // .. to ensure it was not called after stop() + ASSERT_EQ(2, cb_count.load()); + + // restart application (w/ watchdog handler still set) + std::promise its_promise2; + std::thread t2([&]() { + its_promise2.set_value(true); + app_->start(); + }); + EXPECT_TRUE(its_promise2.get_future().get()); + + // wait till watchdog handler has been invoked again (3rd time) + while (2 == cb_count.load()) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + ASSERT_EQ(3, cb_count.load()); + + // clear handler again (must not be called again), this time via zero interval + app_->set_watchdog_handler(std::cref(wd_handler), std::chrono::seconds::zero()); + + // wait doubled interval (used previously).. + std::this_thread::sleep_for(std::chrono::seconds(2)); + // .. to ensure it was not called again + ASSERT_EQ(3, cb_count.load()); + + app_->stop(); + t2.join(); +} + +class someip_application_shutdown_test: public ::testing::Test { + +protected: + void SetUp() { + is_registered_ = false; + is_available_ = false; + + app_ = runtime::get()->create_application("application_test"); + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, + std::bind(&someip_application_shutdown_test::on_message_shutdown, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&someip_application_shutdown_test::on_state, this, + std::placeholders::_1)); + app_->register_availability_handler( + vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&someip_application_shutdown_test::on_availability, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + shutdown_thread_ = std::thread(&someip_application_shutdown_test::send_shutdown_message, this); + + app_->start(); + } + + void TearDown() { + shutdown_thread_.join(); + app_->stop(); + app_.reset(); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + } + + void on_state(vsomeip::state_type_e _state) { + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + std::lock_guard its_lock(mutex_); + is_registered_ = true; + cv_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + (void)_service; + (void)_instance; + if(_is_available) { + std::lock_guard its_lock(mutex_); + is_available_ = _is_available; + cv_.notify_one(); + } + } + + void on_message_shutdown(const std::shared_ptr& _request) + { + (void)_request; + VSOMEIP_INFO << "Shutdown method was called, going down now."; + app_->clear_all_handler(); + app_->stop(); + } + + void send_shutdown_message() { + { + std::unique_lock its_lock(mutex_); + while (!is_registered_) { + if (std::cv_status::timeout + == cv_.wait_for(its_lock, std::chrono::seconds(10))) { + ADD_FAILURE()<< "Application wasn't registered in time!"; + is_registered_ = true; + } + } + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID); + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID); + while (!is_available_) { + if (std::cv_status::timeout + == cv_.wait_for(its_lock, std::chrono::seconds(10))) { + ADD_FAILURE()<< "Service didn't become available in time!"; + is_available_ = true; + } + } + } + + std::shared_ptr r = runtime::get()->create_request(); + r->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + r->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + r->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); + app_->send(r); + } + + bool is_registered_; + bool is_available_; + std::shared_ptr app_; + std::condition_variable cv_; + std::mutex mutex_; + std::thread shutdown_thread_; +}; + +class someip_application_exception_test: public ::testing::Test { + +protected: + void SetUp() { + is_registered_ = false; + is_available_ = false; + exception_method_called_ = false; + + app_ = runtime::get()->create_application("application_test"); + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, + std::bind(&someip_application_exception_test::on_message_shutdown, this, + std::placeholders::_1)); + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN+1, + std::bind(&someip_application_exception_test::on_message_exception, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&someip_application_exception_test::on_state, this, + std::placeholders::_1)); + app_->register_availability_handler( + vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&someip_application_exception_test::on_availability, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + shutdown_thread_ = std::thread(&someip_application_exception_test::send_shutdown_message, this); + + app_->start(); + } + + void TearDown() { + shutdown_thread_.join(); + app_->stop(); + app_.reset(); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + } + + void on_state(vsomeip::state_type_e _state) { + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + std::lock_guard its_lock(mutex_); + is_registered_ = true; + cv_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + (void)_service; + (void)_instance; + if(_is_available) { + std::lock_guard its_lock(mutex_); + is_available_ = _is_available; + cv_.notify_one(); + } + } + + void on_message_shutdown(const std::shared_ptr& _request) + { + (void)_request; + VSOMEIP_INFO << "Shutdown method was called, going down now."; + app_->clear_all_handler(); + app_->stop(); + } + + void on_message_exception(const std::shared_ptr& _request) + { + (void)_request; + { + std::lock_guard its_lock(mutex_); + exception_method_called_ = true; + cv_.notify_one(); + } + throw std::invalid_argument("something went terribly wrong"); + } + + void send_shutdown_message() { + { + std::unique_lock its_lock(mutex_); + while(!is_registered_) { + cv_.wait(its_lock); + } + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID); + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID); + while(!is_available_) { + cv_.wait(its_lock); + } + } + + std::shared_ptr r = runtime::get()->create_request(); + // call method which throws exception + r->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + r->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + r->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN+1); + app_->send(r); + + { + std::unique_lock its_lock(mutex_); + while (!exception_method_called_) { + cv_.wait(its_lock); + } + } + + + //shutdown test + r->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + r->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + r->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); + app_->send(r); + } + + bool is_registered_; + bool is_available_; + bool exception_method_called_; + std::shared_ptr app_; + std::condition_variable cv_; + std::mutex mutex_; + std::thread shutdown_thread_; +}; + +/** + * @test Stop the application through a method invoked from a dispatcher thread + */ +TEST_F(someip_application_shutdown_test, stop_application_from_dispatcher_thread) { + +} + +/** + * @test Catch unhandled exceptions from invoked handlers + */ +TEST_F(someip_application_exception_test, catch_exception_in_invoked_handler) { + +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif + + + + diff --git a/test/network_tests/application_tests/application_test_availability.cpp b/test/network_tests/application_tests/application_test_availability.cpp new file mode 100644 index 0000000..89d94c1 --- /dev/null +++ b/test/network_tests/application_tests/application_test_availability.cpp @@ -0,0 +1,39 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +#include + +#include "application_test_client_availability.cpp" +#include "application_test_service.cpp" +#include "application_test_daemon.cpp" + +TEST(someip_application_test_availability, register_availability_handlers) +{ + // start application acting as daemon + application_test_daemon its_daemon; + + // start receiver service + application_test_service its_receiver(application_test::service); + + // start client + application_test_client_availability its_client(application_test::service); + int counter(0); + while (!its_client.all_availability_handlers_called() && counter < 500) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + counter++; + } + + //shutdown + its_receiver.stop(); + its_client.stop(); + its_daemon.stop(); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/application_tests/application_test_availability_starter.sh b/test/network_tests/application_tests/application_test_availability_starter.sh new file mode 100755 index 0000000..645e347 --- /dev/null +++ b/test/network_tests/application_tests/application_test_availability_starter.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_CONFIGURATION=application_test_single_process.json +./application_test_availability + + exit $? \ No newline at end of file diff --git a/test/network_tests/application_tests/application_test_client.cpp b/test/network_tests/application_tests/application_test_client.cpp new file mode 100644 index 0000000..30d0084 --- /dev/null +++ b/test/network_tests/application_tests/application_test_client.cpp @@ -0,0 +1,199 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "application_test_globals.hpp" + +class application_test_client { +public: + application_test_client(struct application_test::service_info _service_info) : + service_info_(_service_info), + app_(vsomeip::runtime::get()->create_application("client")), + wait_until_registered_(true), + wait_until_service_available_(true), + wait_for_stop_(true), + received_responses_(0), + sent_requests_(0), + stop_called_(false), + stop_thread_(std::bind(&application_test_client::wait_for_stop, this)), + send_thread_(std::bind(&application_test_client::send, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&application_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, + std::bind(&application_test_client::on_message, this, + std::placeholders::_1)); + + // register availability for all other services and request their event. + app_->register_availability_handler(service_info_.service_id, + service_info_.instance_id, + std::bind(&application_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + app_->request_service(service_info_.service_id, + service_info_.instance_id); + std::promise its_promise; + application_thread_ = std::thread([&](){ + its_promise.set_value(true); + app_->start(); + }); + EXPECT_TRUE(its_promise.get_future().get()); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + ~application_test_client() { + send_thread_.join(); + stop_thread_.join(); + application_thread_.join(); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + VSOMEIP_INFO << "Service [" << std::setw(4) + << std::setfill('0') << std::hex << _service << "." << _instance + << "] is " << (_is_available ? "available":"not available") << "."; + std::lock_guard its_lock(mutex_); + if(_is_available) { + wait_until_service_available_ = false; + condition_.notify_one(); + } else { + wait_until_service_available_ = true; + condition_.notify_one(); + } + } + + void on_message(const std::shared_ptr &_message) { + ++received_responses_; + EXPECT_EQ(service_info_.service_id, _message->get_service()); + EXPECT_EQ(service_info_.method_id, _message->get_method()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + VSOMEIP_INFO << "Received a response with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_session() << "]"; + } + + void send() { + std::unique_lock its_lock(mutex_); + while (wait_until_registered_ && !stop_called_) { + condition_.wait_for(its_lock, std::chrono::milliseconds(100)); + } + + while (wait_until_service_available_ && !stop_called_) { + condition_.wait_for(its_lock, std::chrono::milliseconds(100)); + } + its_lock.unlock(); + its_lock.release(); + + for (;;) { + bool send(false); + { + std::lock_guard its_lock(mutex_); + send = !wait_until_service_available_; + } + if (send && !stop_called_) { + std::shared_ptr its_req = vsomeip::runtime::get()->create_request(); + its_req->set_service(service_info_.service_id); + its_req->set_instance(service_info_.instance_id); + its_req->set_method(service_info_.method_id); + app_->send(its_req); + ++sent_requests_; + VSOMEIP_INFO << "Sent a request to the service!"; + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } else { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + if(stop_called_) { + break; + } + } + } + + void wait_for_stop() { + std::unique_lock its_lock(stop_mutex_); + while (wait_for_stop_) { + stop_condition_.wait(its_lock); + } + VSOMEIP_INFO << "going down"; + app_->clear_all_handler(); + app_->stop(); + } + + void stop(bool check) { + stop_called_ = true; + std::lock_guard its_lock(stop_mutex_); + wait_for_stop_ = false; + VSOMEIP_INFO << "going down. Sent " << sent_requests_ + << " requests and received " << received_responses_ + << " responses. Delta: " << sent_requests_ - received_responses_; + std::uint32_t counter(0); + if (check) { + while(sent_requests_ == 0 || sent_requests_ < received_responses_) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + if(++counter > 50) { + break; + } + } + EXPECT_GT(sent_requests_, 0u); + EXPECT_GT(received_responses_, 0u); + EXPECT_EQ(sent_requests_, received_responses_); + } + stop_condition_.notify_one(); + } + +private: + struct application_test::service_info service_info_; + std::shared_ptr app_; + + bool wait_until_registered_; + bool wait_until_service_available_; + std::mutex mutex_; + std::condition_variable condition_; + + bool wait_for_stop_; + std::mutex stop_mutex_; + std::condition_variable stop_condition_; + + std::atomic received_responses_; + std::atomic sent_requests_; + std::atomic stop_called_; + + std::thread stop_thread_; + std::thread send_thread_; + std::thread application_thread_; +}; diff --git a/test/network_tests/application_tests/application_test_client_availability.cpp b/test/network_tests/application_tests/application_test_client_availability.cpp new file mode 100644 index 0000000..16fe87b --- /dev/null +++ b/test/network_tests/application_tests/application_test_client_availability.cpp @@ -0,0 +1,203 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "application_test_globals.hpp" + +class application_test_client_availability { +public: + application_test_client_availability(struct application_test::service_info _service_info) : + service_info_(_service_info), + app_(vsomeip::runtime::get()->create_application("client")), + wait_until_registered_(true), + all_availability_handlers_called_(false), + run_thread_(std::bind(&application_test_client_availability::run, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&application_test_client_availability::on_state, this, + std::placeholders::_1)); + + // register availability handler for every possiblity of + // ANY_SERVICE, ANY_INSTANCE, ANY_MAJOR, ANY_MINOR + for (std::uint32_t i = 0; i < 16; i++) { + vsomeip::service_t its_service = (i & 0x8) ? service_info_.service_id : vsomeip::ANY_SERVICE; + vsomeip::instance_t its_instance = (i & 0x4) ? service_info_.instance_id : vsomeip::ANY_INSTANCE; + vsomeip::major_version_t its_major = (i & 0x2) ? service_info_.major_version : vsomeip::ANY_MAJOR; + vsomeip::minor_version_t its_minor = (i & 0x1) ? service_info_.minor_version : vsomeip::ANY_MINOR; + app_->register_availability_handler(its_service, + its_instance, + std::bind(&application_test_client_availability::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, i), + its_major, its_minor); + VSOMEIP_DEBUG << "Registering: " + << std::setw(4) << std::setfill('0') << std::hex << its_service << "." + << std::setw(4) << std::setfill('0') << std::hex << its_instance << "." + << std::setw(2) << std::setfill('0') << std::hex << (std::uint32_t)its_major << "." + << std::setw(4) << std::setfill('0') << std::hex << its_minor << "." + << i; + + } + app_->register_availability_handler(service_info_.service_id, + service_info_.instance_id, + std::bind(&application_test_client_availability::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, 16), + service_info_.major_version, vsomeip::DEFAULT_MINOR); + VSOMEIP_DEBUG << "Registering: " + << std::setw(4) << std::setfill('0') << std::hex << service_info_.service_id << "." + << std::setw(4) << std::setfill('0') << std::hex << service_info_.instance_id << "." + << std::setw(2) << std::setfill('0') << std::hex << (std::uint32_t)service_info_.service_id << "." + << std::setw(4) << std::setfill('0') << std::hex << vsomeip::DEFAULT_MINOR << "." + << 16; + app_->request_service(service_info_.service_id, + service_info_.instance_id); + std::promise its_promise; + application_thread_ = std::thread([&](){ + its_promise.set_value(true); + app_->start(); + }); + EXPECT_TRUE(its_promise.get_future().get()); + } + + ~application_test_client_availability() { + run_thread_.join(); + application_thread_.join(); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available, + std::uint32_t _handler_index) + { + VSOMEIP_DEBUG<< "Service [" << std::setw(4) << std::setfill('0') << std::hex + << _service << "." << std::setw(4) << std::setfill('0') << _instance << "] is " + << (_is_available ? "available." : "NOT available.") << ". " + << _handler_index; + if(service_info_.service_id == _service + && service_info_.instance_id == _instance) { + std::lock_guard its_lock(availability_handler_called_mutex_); + availability_handler_called_[_handler_index] = _is_available; + availability_condition_.notify_one(); + } + } + + void run() { + { + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + } + while(!app_->is_available(service_info_.service_id, + service_info_.instance_id, service_info_.major_version, + service_info_.minor_version)) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + for (std::uint32_t i = 0; i < 16; i++) { + vsomeip::service_t its_service = (i & 0x8) ? service_info_.service_id : vsomeip::ANY_SERVICE; + vsomeip::instance_t its_instance = (i & 0x4) ? service_info_.instance_id : vsomeip::ANY_INSTANCE; + vsomeip::major_version_t its_major = (i & 0x2) ? service_info_.major_version : vsomeip::ANY_MAJOR; + vsomeip::minor_version_t its_minor = (i & 0x1) ? service_info_.minor_version : vsomeip::ANY_MINOR; + + VSOMEIP_DEBUG << "Calling is_available: " + << std::setw(4) << std::setfill('0') << std::hex << its_service << "." + << std::setw(4) << std::setfill('0') << std::hex << its_instance << "." + << std::setw(2) << std::setfill('0') << std::hex << (std::uint32_t)its_major << "." + << std::setw(4) << std::setfill('0') << std::hex << its_minor; + EXPECT_TRUE(app_->is_available(its_service, its_instance, its_major, its_minor)); + + VSOMEIP_DEBUG << "Calling are_available: " + << std::setw(4) << std::setfill('0') << std::hex << its_service << "." + << std::setw(4) << std::setfill('0') << std::hex << its_instance << "." + << std::setw(2) << std::setfill('0') << std::hex << (std::uint32_t)its_major << "." + << std::setw(4) << std::setfill('0') << std::hex << its_minor; + vsomeip::application::available_t are_available; + EXPECT_TRUE(app_->are_available(are_available, its_service, its_instance, its_major, its_minor)); + bool found(false); + auto found_service = are_available.find(service_info_.service_id); + if(found_service != are_available.end()) { + auto found_instance = found_service->second.find(service_info_.instance_id); + if(found_instance != found_service->second.end()) { + auto found_major = found_instance->second.find(service_info_.major_version); + if (found_major != found_instance->second.end()) { + if (found_major->second == service_info_.minor_version) { + found = true; + } + } + } + } + EXPECT_TRUE(found); + + } + { + std::unique_lock its_lock(availability_handler_called_mutex_); + while(!std::all_of(availability_handler_called_.cbegin(), + availability_handler_called_.cend(), + [&](const availability_handler_called_t::value_type &v) { + return v; + })) { + availability_condition_.wait(its_lock); + } + } + VSOMEIP_INFO <<" Everything is available"; + all_availability_handlers_called_ = true; + } + + void stop() { + VSOMEIP_INFO << "going down"; + app_->clear_all_handler(); + app_->stop(); + } + + bool all_availability_handlers_called() const { + return all_availability_handlers_called_; + } + +private: + struct application_test::service_info service_info_; + std::shared_ptr app_; + std::mutex availability_handler_called_mutex_; + std::condition_variable availability_condition_; + typedef std::array availability_handler_called_t; + availability_handler_called_t availability_handler_called_; + + + bool wait_until_registered_; + std::mutex mutex_; + std::condition_variable condition_; + std::atomic all_availability_handlers_called_; + std::thread run_thread_; + std::thread application_thread_; +}; diff --git a/test/network_tests/application_tests/application_test_daemon.cpp b/test/network_tests/application_tests/application_test_daemon.cpp new file mode 100644 index 0000000..2f0b244 --- /dev/null +++ b/test/network_tests/application_tests/application_test_daemon.cpp @@ -0,0 +1,42 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include + +#include +#include + +class application_test_daemon { +public: + application_test_daemon() : + app_(vsomeip::runtime::get()->create_application("daemon")) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + std::promise its_promise; + application_thread_ = std::thread([&](){ + its_promise.set_value(true); + app_->start(); + }); + EXPECT_TRUE(its_promise.get_future().get()); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + VSOMEIP_INFO << "Daemon starting"; + } + + ~application_test_daemon() { + application_thread_.join(); + } + + void stop() { + VSOMEIP_INFO << "Daemon stopping"; + app_->stop(); + } + +private: + std::shared_ptr app_; + std::thread application_thread_; +}; diff --git a/test/network_tests/application_tests/application_test_globals.hpp b/test/network_tests/application_tests/application_test_globals.hpp new file mode 100644 index 0000000..7caa9db --- /dev/null +++ b/test/network_tests/application_tests/application_test_globals.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef APPLICATION_TEST_GLOBALS_HPP_ +#define APPLICATION_TEST_GLOBALS_HPP_ + +namespace application_test { + +struct service_info { + vsomeip::service_t service_id; + vsomeip::instance_t instance_id; + vsomeip::method_t method_id; + vsomeip::event_t event_id; + vsomeip::eventgroup_t eventgroup_id; + vsomeip::method_t shutdown_method_id; + vsomeip::major_version_t major_version; + vsomeip::minor_version_t minor_version; +}; + + +struct service_info service = { 0x1111, 0x1, 0x1111, 0x1111, 0x1000, 0x1404, 0x2, 0x4711 }; + +static constexpr int number_of_messages_to_send = 150; +} + +#endif /* APPLICATION_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/application_tests/application_test_service.cpp b/test/network_tests/application_tests/application_test_service.cpp new file mode 100644 index 0000000..77d40cd --- /dev/null +++ b/test/network_tests/application_tests/application_test_service.cpp @@ -0,0 +1,128 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "application_test_globals.hpp" + +class application_test_service { +public: + application_test_service(struct application_test::service_info _service_info) : + service_info_(_service_info), + // service with number 1 uses "routingmanagerd" as application name + // this way the same json file can be reused for all local tests + // including the ones with routingmanagerd + app_(vsomeip::runtime::get()->create_application("service")), + wait_until_registered_(true), + stop_called_(false), + offer_thread_(std::bind(&application_test_service::run, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&application_test_service::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.method_id, + std::bind(&application_test_service::on_request, this, + std::placeholders::_1)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.shutdown_method_id, + std::bind(&application_test_service::on_shutdown_method_called, this, + std::placeholders::_1)); + std::promise its_promise; + application_thread_ = std::thread([&](){ + its_promise.set_value(true); + app_->start(); + }); + EXPECT_TRUE(its_promise.get_future().get()); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + ~application_test_service() { + offer_thread_.join(); + application_thread_.join(); + } + + + void offer() { + app_->offer_service(service_info_.service_id, service_info_.instance_id, + service_info_.major_version, service_info_.minor_version); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_request(const std::shared_ptr &_message) { + app_->send(vsomeip::runtime::get()->create_response(_message)); + VSOMEIP_INFO << "Received a request with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_session() << "]"; + } + + void on_shutdown_method_called(const std::shared_ptr &_message) { + (void)_message; + stop(); + } + + void stop() { + stop_called_ = true; + app_->stop_offer_service(service_info_.service_id, service_info_.instance_id, + service_info_.major_version, service_info_.minor_version); + app_->clear_all_handler(); + app_->stop(); + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + std::unique_lock its_lock(mutex_); + while (wait_until_registered_ && !stop_called_) { + condition_.wait_for(its_lock, std::chrono::milliseconds(100)); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + } + +private: + struct application_test::service_info service_info_; + std::shared_ptr app_; + + bool wait_until_registered_; + std::mutex mutex_; + std::condition_variable condition_; + std::atomic stop_called_; + std::thread offer_thread_; + std::thread application_thread_; +}; diff --git a/test/network_tests/application_tests/application_test_single_process.cpp b/test/network_tests/application_tests/application_test_single_process.cpp new file mode 100644 index 0000000..c738899 --- /dev/null +++ b/test/network_tests/application_tests/application_test_single_process.cpp @@ -0,0 +1,47 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include "application_test_service.cpp" +#include "application_test_client.cpp" +#include "application_test_daemon.cpp" + +TEST(someip_application_test_single_process, notify_increasing_counter) +{ + // start application acting as daemon (rm_stub) + auto its_daemon = std::make_shared(); + + // start receiver service (rm_proxy) + application_test_service its_receiver(application_test::service); + + // stop the daemon (rm_stub goes away) + its_daemon->stop(); + its_daemon.reset(); + // restart client which tries to communicate with service multiple times + // thus it will always be the new routing manager + for (int var = 0; var < 10; ++var) { + // every time the client is restarted it becomes the rm_stub again + application_test_client its_client(application_test::service); + if(var != 9) { + its_client.stop(false); + } else { + // for the last iteration we sleep to make sure the communication + // between the client and the service can be established + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + its_client.stop(true); + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + its_receiver.on_shutdown_method_called(vsomeip::runtime::get()->create_message()); +} + + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/application_tests/application_test_single_process.json b/test/network_tests/application_tests/application_test_single_process.json new file mode 100644 index 0000000..b604d9a --- /dev/null +++ b/test/network_tests/application_tests/application_test_single_process.json @@ -0,0 +1,14 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/someip.log" + }, + "dlt":"false" + } +} diff --git a/test/network_tests/application_tests/application_test_single_process_starter.sh b/test/network_tests/application_tests/application_test_single_process_starter.sh new file mode 100755 index 0000000..3919358 --- /dev/null +++ b/test/network_tests/application_tests/application_test_single_process_starter.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 + +export VSOMEIP_CONFIGURATION=application_test_single_process.json +./application_test_single_process + +if [ $? -ne 0 ] +then + ((FAIL+=1)) +fi + +# Check if both exited successfully +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/application_tests/application_test_starter.sh b/test/network_tests/application_tests/application_test_starter.sh new file mode 100755 index 0000000..7e8c022 --- /dev/null +++ b/test/network_tests/application_tests/application_test_starter.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 + +export VSOMEIP_CONFIGURATION=application_test_no_dispatch_threads.json +./application_test + +if [ $? -ne 0 ] +then + ((FAIL+=1)) +fi + +export VSOMEIP_CONFIGURATION=application_test.json +./application_test + +if [ $? -ne 0 ] +then + ((FAIL+=1)) +fi + +cat <create_application("big_payload_test_client")), + request_(vsomeip::runtime::get()->create_request(_use_tcp)), + blocked_(false), + is_available_(false), + test_mode_(_test_mode), + number_of_messages_to_send_( + test_mode_ == big_payload_test::test_mode::RANDOM ? + big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES_RANDOM : + big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES), + number_of_sent_messages_(0), + number_of_acknowledged_messages_(0), + sender_(std::bind(&big_payload_test_client::run, this)) { + switch (test_mode_) { + case big_payload_test::test_mode::RANDOM: + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_RANDOM; + break; + case big_payload_test::test_mode::LIMITED: + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_LIMITED; + break; + case big_payload_test::test_mode::LIMITED_GENERAL: + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_LIMITED_GENERAL; + break; + case big_payload_test::test_mode::QUEUE_LIMITED_GENERAL: + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_QUEUE_LIMITED_GENERAL; + break; + case big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC: + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_QUEUE_LIMITED_SPECIFIC; + break; + case big_payload_test::test_mode::UDP: + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_UDP; + break; + default: + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID; + break; + } +} + +bool big_payload_test_client::init() +{ + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + + app_->register_state_handler( + std::bind(&big_payload_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, + std::bind(&big_payload_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(service_id_, + big_payload_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&big_payload_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + return true; +} + +void big_payload_test_client::start() +{ + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void big_payload_test_client::stop() +{ + VSOMEIP_INFO << "Stopping..."; + if (test_mode_ == big_payload_test::test_mode::LIMITED + || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + EXPECT_EQ(number_of_acknowledged_messages_, number_of_messages_to_send_ / 4); + } else if (test_mode_ == big_payload_test::test_mode::UDP) { + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + EXPECT_EQ(number_of_acknowledged_messages_, number_of_messages_to_send_); + } + app_->clear_all_handler(); + app_->stop(); +} + +void big_payload_test_client::join_sender_thread(){ + sender_.join(); + if (test_mode_ == big_payload_test::test_mode::LIMITED + || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { + EXPECT_EQ(number_of_acknowledged_messages_, number_of_messages_to_send_ / 4); + } else if (test_mode_ == big_payload_test::test_mode::UDP) { + EXPECT_EQ(number_of_sent_messages_, number_of_acknowledged_messages_); + } else { + EXPECT_EQ(number_of_sent_messages_, number_of_acknowledged_messages_); + } +} + +void big_payload_test_client::on_state(vsomeip::state_type_e _state) +{ + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + app_->request_service(service_id_, + big_payload_test::TEST_SERVICE_INSTANCE_ID, false); + } +} + +void big_payload_test_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) +{ + VSOMEIP_INFO << "Service [" << std::setw(4) << std::setfill('0') << std::hex + << _service << "." << _instance << "] is " + << (_is_available ? "available." : "NOT available."); + + if(service_id_ == _service + && big_payload_test::TEST_SERVICE_INSTANCE_ID == _instance) + { + if(is_available_ && !_is_available) + { + is_available_ = false; + } + else if(_is_available && !is_available_) + { + is_available_ = true; + send(); + } + } +} + +void big_payload_test_client::on_message(const std::shared_ptr& _response) +{ + VSOMEIP_INFO << "Received a response from Service [" << std::setw(4) + << std::setfill('0') << std::hex << _response->get_service() << "." + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_instance() << "] to Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_client() << "/" << std::setw(4) + << std::setfill('0') << std::hex << _response->get_session() + << "] size: " << std::dec << _response->get_payload()->get_length(); + static vsomeip::session_t last_session(0); + ASSERT_GT(_response->get_session(), last_session); + last_session = _response->get_session(); + + if(test_mode_ == big_payload_test::test_mode::RANDOM) { + ASSERT_LT(_response->get_payload()->get_length(), big_payload_test::BIG_PAYLOAD_SIZE_RANDOM); + } else if (test_mode_ == big_payload_test::test_mode::UDP) { + EXPECT_EQ(big_payload_test::BIG_PAYLOAD_SIZE_UDP, _response->get_payload()->get_length()); + } else { + ASSERT_EQ(_response->get_payload()->get_length(), big_payload_test::BIG_PAYLOAD_SIZE); + } + + bool check(true); + vsomeip::length_t len = _response->get_payload()->get_length(); + vsomeip::byte_t* datap = _response->get_payload()->get_data(); + for(unsigned int i = 0; i < len; ++i) { + check = check && datap[i] == big_payload_test::DATA_SERVICE_TO_CLIENT; + } + if(!check) { + GTEST_FATAL_FAILURE_("wrong data transmitted"); + } + number_of_acknowledged_messages_++; + if (test_mode_ == big_payload_test::test_mode::LIMITED + || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { + if (number_of_acknowledged_messages_ == number_of_messages_to_send_ / 4) { + send(); + } + } else if ( number_of_acknowledged_messages_ == number_of_messages_to_send_) { + send(); + } +} + +void big_payload_test_client::send() +{ + std::lock_guard its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); +} + +void big_payload_test_client::run() +{ + std::unique_lock its_lock(mutex_); + while (!blocked_) + { + condition_.wait(its_lock); + } + blocked_ = false; + + request_->set_service(service_id_); + request_->set_instance(big_payload_test::TEST_SERVICE_INSTANCE_ID); + request_->set_method(big_payload_test::TEST_SERVICE_METHOD_ID); + + std::srand(static_cast(std::time(0))); + + std::shared_ptr its_payload = + vsomeip::runtime::get()->create_payload(); + std::vector its_payload_data; + + for (unsigned int i = 0; i < number_of_messages_to_send_; i++) + { + if (test_mode_ == big_payload_test::test_mode::RANDOM) { + unsigned int datasize(static_cast(std::rand()) % big_payload_test::BIG_PAYLOAD_SIZE_RANDOM); + its_payload_data.assign(datasize, big_payload_test::DATA_CLIENT_TO_SERVICE); + } else if (test_mode_ == big_payload_test::test_mode::LIMITED + || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { + if (i % 2) { + // try to sent a too big payload for half of the messages + its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE + 1, + big_payload_test::DATA_CLIENT_TO_SERVICE); + } else { + its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE, + big_payload_test::DATA_CLIENT_TO_SERVICE); + } + } else if (test_mode_ == big_payload_test::test_mode::UDP) { + its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE_UDP, + big_payload_test::DATA_CLIENT_TO_SERVICE); + } else { + its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE, + big_payload_test::DATA_CLIENT_TO_SERVICE); + } + its_payload->set_data(its_payload_data); + request_->set_payload(its_payload); + app_->send(request_); + if (test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + VSOMEIP_INFO << "Client/Session [" << std::setw(4) << std::setfill('0') + << std::hex << request_->get_client() << "/" << std::setw(4) + << std::setfill('0') << std::hex << request_->get_session() + << "] sent a request to Service [" << std::setw(4) + << std::setfill('0') << std::hex << request_->get_service() + << "." << std::setw(4) << std::setfill('0') << std::hex + << request_->get_instance() << "] size: " << std::dec << + request_->get_payload()->get_length(); + number_of_sent_messages_++; + } + while(!blocked_) { + if (std::cv_status::timeout + == condition_.wait_for(its_lock, std::chrono::seconds(120))) { + GTEST_FATAL_FAILURE_("Didn't receive all replies within time"); + } else { + if (test_mode_ == big_payload_test::LIMITED + || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { + EXPECT_EQ(number_of_messages_to_send_ / 4, + number_of_acknowledged_messages_); + } else { + EXPECT_EQ(number_of_sent_messages_, + number_of_acknowledged_messages_); + } + } + } + stop(); +} + +static big_payload_test::test_mode test_mode(big_payload_test::test_mode::UNKNOWN); + +TEST(someip_big_payload_test, send_ten_messages_to_service) +{ + bool use_tcp = (test_mode != big_payload_test::test_mode::UDP); + big_payload_test_client test_client_(use_tcp, test_mode); + if (test_client_.init()) { + test_client_.start(); + test_client_.join_sender_thread(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if (argc > 1) { + if (std::string("RANDOM") == std::string(argv[1])) { + test_mode = big_payload_test::test_mode::RANDOM; + } else if (std::string("LIMITED") == std::string(argv[1])) { + test_mode = big_payload_test::test_mode::LIMITED; + } else if (std::string("LIMITEDGENERAL") == std::string(argv[1])) { + test_mode = big_payload_test::test_mode::LIMITED_GENERAL; + } else if (std::string("QUEUELIMITEDGENERAL") == std::string(argv[1])) { + test_mode = big_payload_test::test_mode::QUEUE_LIMITED_GENERAL; + } else if (std::string("QUEUELIMITEDSPECIFIC") == std::string(argv[1])) { + test_mode = big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC; + } else if (std::string("UDP") == std::string(argv[1])) { + test_mode = big_payload_test::test_mode::UDP; + } + } + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/big_payload_tests/big_payload_test_client.hpp b/test/network_tests/big_payload_tests/big_payload_test_client.hpp new file mode 100644 index 0000000..bb81fdc --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_client.hpp @@ -0,0 +1,52 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef BIGPAYLOADTESTCLIENT_HPP_ +#define BIGPAYLOADTESTCLIENT_HPP_ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "big_payload_test_globals.hpp" +#include + +class big_payload_test_client +{ +public: + big_payload_test_client(bool _use_tcp, big_payload_test::test_mode _random_mode); + bool init(); + void start(); + void stop(); + void join_sender_thread(); + void on_state(vsomeip::state_type_e _state); + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available); + void on_message(const std::shared_ptr &_response); + void send(); + void run(); + +private: + std::shared_ptr app_; + std::shared_ptr request_; + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + bool is_available_; + big_payload_test::test_mode test_mode_; + std::uint32_t number_of_messages_to_send_; + std::uint32_t number_of_sent_messages_; + std::atomic number_of_acknowledged_messages_; + std::thread sender_; + vsomeip::service_t service_id_; +}; + +#endif /* BIGPAYLOADTESTCLIENT_HPP_ */ diff --git a/test/network_tests/big_payload_tests/big_payload_test_client_local_start.sh b/test/network_tests/big_payload_tests/big_payload_test_client_local_start.sh new file mode 100755 index 0000000..adbf9f4 --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_client_local_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Start the client +export VSOMEIP_APPLICATION_NAME=big_payload_test_client +export VSOMEIP_CONFIGURATION=big_payload_test_local.json +./big_payload_test_client diff --git a/test/network_tests/big_payload_tests/big_payload_test_external_client_start.sh b/test/network_tests/big_payload_tests/big_payload_test_external_client_start.sh new file mode 100755 index 0000000..5258ce8 --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_external_client_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Start the client +export VSOMEIP_APPLICATION_NAME=big_payload_test_client +export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client.json +./big_payload_test_client diff --git a/test/network_tests/big_payload_tests/big_payload_test_external_service_start.sh b/test/network_tests/big_payload_tests/big_payload_test_external_service_start.sh new file mode 100755 index 0000000..ac8dd60 --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_external_service_start.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +if [[ $# -gt 0 && $1 != "RANDOM" && $1 != "LIMITED" && $1 != "LIMITEDGENERAL" && $1 != "QUEUELIMITEDGENERAL" && $1 != "QUEUELIMITEDSPECIFIC" && $1 != "UDP" ]] +then + echo "The only allowed parameter to this script is RANDOM, LIMITED, LIMITEDGENERAL, QUEUELIMITEDGENERAL, QUEUELIMITEDSPECIFIC or UDP" + echo "Like $0 RANDOM" + exit 1 +fi + +# Start the service +if [[ $# -gt 0 && $1 == "RANDOM" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_tcp_service_random.json +elif [[ $# -gt 0 && $1 == "LIMITEDGENERAL" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_tcp_service_limited_general.json +elif [[ $# -gt 0 && $1 == "QUEUELIMITEDGENERAL" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_tcp_service_queue_limited_general.json +elif [[ $# -gt 0 && $1 == "QUEUELIMITEDSPECIFIC" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_tcp_service_queue_limited_specific.json +elif [[ $# -gt 0 && $1 == "UDP" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_udp_service.json +else + export VSOMEIP_CONFIGURATION=big_payload_test_tcp_service.json +fi +./big_payload_test_service $1 diff --git a/test/network_tests/big_payload_tests/big_payload_test_external_starter.sh b/test/network_tests/big_payload_tests/big_payload_test_external_starter.sh new file mode 100755 index 0000000..58d20d7 --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_external_starter.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit successfully. + +if [[ $# -gt 0 && $1 != "RANDOM" && $1 != "LIMITED" && $1 != "LIMITEDGENERAL" && $1 != "QUEUELIMITEDGENERAL" && $1 != "QUEUELIMITEDSPECIFIC" && $1 != "UDP" ]] +then + echo "The only allowed parameter to this script is RANDOM or LIMITED, LIMITEDGENERAL, QUEUELIMITEDGENERAL, QUEUELIMITEDSPECIFIC or UDP" + echo "Like $0 RANDOM" + exit 1 +fi + +FAIL=0 + +# Start the client +if [[ $# -gt 0 && $1 == "RANDOM" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client_random.json +elif [[ $# -gt 0 && $1 == "LIMITEDGENERAL" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client_limited_general.json +elif [[ $# -gt 0 && $1 == "QUEUELIMITEDGENERAL" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client_queue_limited_general.json +elif [[ $# -gt 0 && $1 == "QUEUELIMITEDSPECIFIC" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client_queue_limited_specific.json +elif [[ $# -gt 0 && $1 == "UDP" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_udp_client.json +else + export VSOMEIP_CONFIGURATION=big_payload_test_tcp_client.json +fi +./big_payload_test_client $1 & +BIG_PAYLOAD_TEST_PID=$! + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting big payload test on slave LXC" + if [[ $# -gt 0 ]]; then + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./big_payload_test_external_service_start.sh $1\"" & + else + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./big_payload_test_external_service_start.sh"' & + fi +elif [ ! -z "$USE_DOCKER" ]; then + if [[ $# -gt 0 ]]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./big_payload_test_external_service_start.sh $1" & + else + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./big_payload_test_external_service_start.sh" & + fi +else +cat < + +namespace big_payload_test { + constexpr std::uint32_t BIG_PAYLOAD_SIZE = 1024*600; + constexpr std::uint32_t BIG_PAYLOAD_SIZE_UDP = 1024*30; + constexpr std::uint32_t BIG_PAYLOAD_SIZE_RANDOM = 1024*1024*10; + constexpr vsomeip::byte_t DATA_SERVICE_TO_CLIENT = 0xAA; + constexpr vsomeip::byte_t DATA_CLIENT_TO_SERVICE = 0xFF; + + constexpr std::uint32_t BIG_PAYLOAD_TEST_NUMBER_MESSAGES = 10; + constexpr std::uint32_t BIG_PAYLOAD_TEST_NUMBER_MESSAGES_RANDOM = 50; + + constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID = 0x1234; + constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_LIMITED = 0x1235; + constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_RANDOM = 0x1236; + constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_LIMITED_GENERAL = 0x1237; + constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_QUEUE_LIMITED_GENERAL = 0x1238; + constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_QUEUE_LIMITED_SPECIFIC = 0x1239; + constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID_UDP = 0x1240; + + constexpr vsomeip::service_t TEST_SERVICE_INSTANCE_ID = 0x1; + constexpr vsomeip::method_t TEST_SERVICE_METHOD_ID = 0x8421; + + enum test_mode { + RANDOM, + LIMITED, + LIMITED_GENERAL, + QUEUE_LIMITED_GENERAL, + QUEUE_LIMITED_SPECIFIC, + UDP, + UNKNOWN + }; +} + +#endif /* BIG_PAYLOAD_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/big_payload_tests/big_payload_test_local.json b/test/network_tests/big_payload_tests/big_payload_test_local.json new file mode 100644 index 0000000..983dea6 --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_local.json @@ -0,0 +1,56 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"debug", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatchers" : "0" + }, + { + "name":"big_payload_test_client", + "id":"0x1344", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678" + } + ], + "payload-sizes": + [ + { + "unicast":"127.0.0.1", + "ports": + [ + { + "port":"30509", + "max-payload-size":"614400" + } + ] + } + ], + "routing":"big_payload_test_service", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} + diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_limited.json b/test/network_tests/big_payload_tests/big_payload_test_local_limited.json new file mode 100644 index 0000000..4e8c666 --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_local_limited.json @@ -0,0 +1,44 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"error", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatchers" : "0" + }, + { + "name":"big_payload_test_client", + "id":"0x1344", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678" + } + ], + "max-payload-size-local" : "614400", + "routing":"big_payload_test_service", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} + diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_queue_limited.json b/test/network_tests/big_payload_tests/big_payload_test_local_queue_limited.json new file mode 100644 index 0000000..584e77e --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_local_queue_limited.json @@ -0,0 +1,44 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"error", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatchers" : "0" + }, + { + "name":"big_payload_test_client", + "id":"0x1344", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678" + } + ], + "endpoint-queue-limit-local" : "614431", + "routing":"big_payload_test_service", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} + diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_random.json b/test/network_tests/big_payload_tests/big_payload_test_local_random.json new file mode 100644 index 0000000..0cf2081 --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_local_random.json @@ -0,0 +1,44 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"debug", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatchers" : "0" + }, + { + "name":"big_payload_test_client", + "id":"0x1344", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678" + } + ], + "buffer-shrink-threshold" : "2", + "routing":"big_payload_test_service", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} + diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_starter.sh b/test/network_tests/big_payload_tests/big_payload_test_local_starter.sh new file mode 100755 index 0000000..6439cac --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_local_starter.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit successfully. + +if [[ $# -gt 0 && $1 != "RANDOM" && $1 != "LIMITED" && $1 != "QUEUELIMITEDGENERAL" ]] +then + echo "The only allowed parameter to this script is RANDOM or LIMITED or QUEUELIMITEDGENERAL." + echo "Like $0 RANDOM" + exit 1 +fi + + +FAIL=0 + +# Start the service +if [[ $# -gt 0 && $1 == "RANDOM" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_local_random.json +elif [[ $# -gt 0 && $1 == "LIMITED" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_local_limited.json +elif [[ $# -gt 0 && $1 == "QUEUELIMITEDGENERAL" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_local_queue_limited.json +else + export VSOMEIP_CONFIGURATION=big_payload_test_local.json +fi +./big_payload_test_service $1 & + +# Start the client +./big_payload_test_client $1 & + +# Wait until client and service are finished +for job in $(jobs -p) +do + # Fail gets incremented if either client or service exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +# Check if client and server both exited successfully +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_tcp_client_start.sh b/test/network_tests/big_payload_tests/big_payload_test_local_tcp_client_start.sh new file mode 100755 index 0000000..bc7fc97 --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_local_tcp_client_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Start the client +export VSOMEIP_APPLICATION_NAME=big_payload_test_client +export VSOMEIP_CONFIGURATION=big_payload_test_local_tcp_client.json +./big_payload_test_client diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_tcp_service_start.sh b/test/network_tests/big_payload_tests/big_payload_test_local_tcp_service_start.sh new file mode 100755 index 0000000..5bc73fc --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_local_tcp_service_start.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +if [[ $# -gt 0 && $1 != "RANDOM" && $1 != "LIMITED" && $1 != "QUEUELIMITEDGENERAL" ]] +then + echo "The only allowed parameter to this script is RANDOM, LIMITED or QUEUELIMITEDGENERAL" + echo "Like $0 RANDOM" + exit 1 +fi + +# Start the service +if [[ $# -gt 0 && $1 == "RANDOM" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_local_tcp_service_random.json +elif [[ $# -gt 0 && $1 == "LIMITED" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_local_tcp_service_limited.json +elif [[ $# -gt 0 && $1 == "QUEUELIMITEDGENERAL" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_local_tcp_service_queue_limited.json +else + export VSOMEIP_CONFIGURATION=big_payload_test_local_tcp_service.json +fi +./big_payload_test_service $1 diff --git a/test/network_tests/big_payload_tests/big_payload_test_local_tcp_starter.sh b/test/network_tests/big_payload_tests/big_payload_test_local_tcp_starter.sh new file mode 100755 index 0000000..633b8f2 --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_local_tcp_starter.sh @@ -0,0 +1,74 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit successfully. + +if [[ $# -gt 0 && $1 != "RANDOM" && $1 != "LIMITED" && $1 != "QUEUELIMITEDGENERAL" ]] +then + echo "The only allowed parameter to this script is RANDOM or LIMITED or QUEUELIMITEDGENERAL." + echo "Like $0 RANDOM" + exit 1 +fi + + +FAIL=0 + +# Start the service +if [[ $# -gt 0 && $1 == "RANDOM" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_local_tcp_client_random.json +elif [[ $# -gt 0 && $1 == "LIMITED" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_local_tcp_client_limited.json +elif [[ $# -gt 0 && $1 == "QUEUELIMITEDGENERAL" ]]; then + export VSOMEIP_CONFIGURATION=big_payload_test_local_tcp_client_queue_limited.json +else + export VSOMEIP_CONFIGURATION=big_payload_test_local_tcp_client.json +fi +./big_payload_test_client $1 & +BIG_PAYLOAD_TEST_PID=$! + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting big payload test on slave LXC" + if [[ $# -gt 0 ]]; then + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./big_payload_test_local_tcp_service_start.sh $1\"" & + else + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./big_payload_test_local_tcp_service_start.sh"' & + fi +elif [ ! -z "$USE_DOCKER" ]; then + if [[ $# -gt 0 ]]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./big_payload_test_local_tcp_service_start.sh $1" & + else + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./big_payload_test_local_tcp_service_start.sh" & + fi +else +cat <create_application("big_payload_test_service")), + is_registered_(false), + blocked_(false), + test_mode_(_test_mode), + number_of_received_messages_(0), + offer_thread_(std::bind(&big_payload_test_service::run, this)) +{ + switch (test_mode_) { + case big_payload_test::test_mode::RANDOM: + expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES_RANDOM; + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_RANDOM; + break; + case big_payload_test::test_mode::LIMITED: + expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES / 2; + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_LIMITED; + break; + case big_payload_test::test_mode::LIMITED_GENERAL: + expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES / 2; + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_LIMITED_GENERAL; + break; + case big_payload_test::test_mode::QUEUE_LIMITED_GENERAL: + expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES / 2; + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_QUEUE_LIMITED_GENERAL; + break; + case big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC: + expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES / 2; + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_QUEUE_LIMITED_SPECIFIC; + break; + case big_payload_test::test_mode::UDP: + expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES; + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID_UDP; + break; + default: + expected_messages_ = big_payload_test::BIG_PAYLOAD_TEST_NUMBER_MESSAGES; + service_id_ = big_payload_test::TEST_SERVICE_SERVICE_ID; + break; + } +} + +bool big_payload_test_service::init() +{ + std::lock_guard its_lock(mutex_); + std::srand(static_cast(std::time(0))); + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + app_->register_message_handler(vsomeip::ANY_SERVICE, + big_payload_test::TEST_SERVICE_INSTANCE_ID, + big_payload_test::TEST_SERVICE_METHOD_ID, + std::bind(&big_payload_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&big_payload_test_service::on_state, this, + std::placeholders::_1)); + return true; +} + +void big_payload_test_service::start() +{ + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void big_payload_test_service::stop() +{ + VSOMEIP_INFO << "Stopping..."; + stop_offer(); + app_->clear_all_handler(); + app_->stop(); +} + +void big_payload_test_service::join_offer_thread() +{ + offer_thread_.join(); +} + +void big_payload_test_service::detach_offer_thread() +{ + offer_thread_.detach(); +} + +void big_payload_test_service::offer() { + app_->offer_service(service_id_, + big_payload_test::TEST_SERVICE_INSTANCE_ID); +} + +void big_payload_test_service::stop_offer() { + app_->stop_offer_service(service_id_, + big_payload_test::TEST_SERVICE_INSTANCE_ID); +} + +void big_payload_test_service::on_state(vsomeip::state_type_e _state) +{ + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : + "deregistered."); + + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + if(!is_registered_) + { + is_registered_ = true; + std::lock_guard its_lock(mutex_); + blocked_ = true; + // "start" the run method thread + condition_.notify_one(); + } + } + else + { + is_registered_ = false; + } +} + +void big_payload_test_service::on_message(const std::shared_ptr& _request) +{ + VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _request->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _request->get_session() << "] size: " << std::dec + << _request->get_payload()->get_length(); + { + std::lock_guard its_lock(mutex_); + incoming_requests_.push(_request); + condition_.notify_one(); + } + + +} + +void big_payload_test_service::run() +{ + { + std::unique_lock its_lock(mutex_); + while (!blocked_) { + condition_.wait(its_lock); + } + + offer(); + + // wait for shutdown + blocked_ = false; + while (!blocked_ || !incoming_requests_.empty()) { + if (incoming_requests_.empty()) { + condition_.wait(its_lock); + } + auto _request = incoming_requests_.front(); + incoming_requests_.pop(); + number_of_received_messages_++; + its_lock.unlock(); + + static vsomeip::session_t last_session(0); + ASSERT_GT(_request->get_session(), last_session); + last_session = _request->get_session(); + if (test_mode_ == big_payload_test::test_mode::RANDOM) { + EXPECT_LT(_request->get_payload()->get_length(), big_payload_test::BIG_PAYLOAD_SIZE_RANDOM); + } else if (test_mode_ == big_payload_test::test_mode::UDP) { + EXPECT_EQ(big_payload_test::BIG_PAYLOAD_SIZE_UDP, _request->get_payload()->get_length()); + } else { + EXPECT_EQ(big_payload_test::BIG_PAYLOAD_SIZE, _request->get_payload()->get_length()); + } + bool check(true); + vsomeip::length_t len = _request->get_payload()->get_length(); + vsomeip::byte_t* datap = _request->get_payload()->get_data(); + for(unsigned int i = 0; i < len; ++i) { + check = check && datap[i] == big_payload_test::DATA_CLIENT_TO_SERVICE; + } + if(!check) { + GTEST_FATAL_FAILURE_("wrong data transmitted"); + } + + // send response + std::shared_ptr its_response = + vsomeip::runtime::get()->create_response(_request); + + std::shared_ptr its_payload = vsomeip::runtime::get() + ->create_payload(); + std::vector its_payload_data; + if (test_mode_ == big_payload_test::test_mode::RANDOM) { + its_payload_data.assign(static_cast(std::rand()) % big_payload_test::BIG_PAYLOAD_SIZE_RANDOM, + big_payload_test::DATA_SERVICE_TO_CLIENT); + } else if (test_mode_ == big_payload_test::test_mode::LIMITED + || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC) { + if (number_of_received_messages_ % 2) { + // try to send to big response for half of the received messsages. + // this way the client will only get replies for a fourth of his sent + // requests as he tries to sent to big data for every second request + // as well + its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE + 1, + big_payload_test::DATA_SERVICE_TO_CLIENT); + } else { + its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE, + big_payload_test::DATA_SERVICE_TO_CLIENT); + } + } else if (test_mode_ == big_payload_test::test_mode::UDP) { + its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE_UDP, + big_payload_test::DATA_SERVICE_TO_CLIENT); + } else { + its_payload_data.assign(big_payload_test::BIG_PAYLOAD_SIZE, + big_payload_test::DATA_SERVICE_TO_CLIENT); + } + + its_payload->set_data(its_payload_data); + its_response->set_payload(its_payload); + + app_->send(its_response); + + if(number_of_received_messages_ == expected_messages_) { + ASSERT_EQ(expected_messages_, number_of_received_messages_); + blocked_ = true; + } + its_lock.lock(); + } + } + std::this_thread::sleep_for(std::chrono::seconds(3)); + if (test_mode_ == big_payload_test::test_mode::LIMITED + || test_mode_ == big_payload_test::test_mode::LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_GENERAL + || test_mode_ == big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC + || test_mode_ == big_payload_test::test_mode::UDP) { + EXPECT_EQ(expected_messages_, number_of_received_messages_); + } + stop(); +} + +static big_payload_test::test_mode test_mode(big_payload_test::test_mode::UNKNOWN); + + +TEST(someip_big_payload_test, receive_ten_messages_and_send_reply) +{ + big_payload_test_service test_service(test_mode); + if (test_service.init()) { + test_service.start(); + test_service.join_offer_thread(); + } else { + test_service.detach_offer_thread(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if (argc > 1) { + if (std::string("RANDOM") == std::string(argv[1])) { + test_mode = big_payload_test::test_mode::RANDOM; + } else if (std::string("LIMITED") == std::string(argv[1])) { + test_mode = big_payload_test::test_mode::LIMITED; + } else if (std::string("LIMITEDGENERAL") == std::string(argv[1])) { + test_mode = big_payload_test::test_mode::LIMITED_GENERAL; + } else if (std::string("QUEUELIMITEDGENERAL") == std::string(argv[1])) { + test_mode = big_payload_test::test_mode::QUEUE_LIMITED_GENERAL; + } else if (std::string("QUEUELIMITEDSPECIFIC") == std::string(argv[1])) { + test_mode = big_payload_test::test_mode::QUEUE_LIMITED_SPECIFIC; + } else if (std::string("UDP") == std::string(argv[1])) { + test_mode = big_payload_test::test_mode::UDP; + } + } + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/big_payload_tests/big_payload_test_service.hpp b/test/network_tests/big_payload_tests/big_payload_test_service.hpp new file mode 100644 index 0000000..44af28a --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_service.hpp @@ -0,0 +1,51 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef BIGPAYLOADTESTSERVICE_HPP_ +#define BIGPAYLOADTESTSERVICE_HPP_ +#include + +#include + +#include +#include +#include +#include +#include + +#include "big_payload_test_globals.hpp" +#include + + +class big_payload_test_service +{ +public: + big_payload_test_service(big_payload_test::test_mode _test_mode); + bool init(); + void start(); + void stop(); + void offer(); + void stop_offer(); + void join_offer_thread(); + void detach_offer_thread(); + void on_state(vsomeip::state_type_e _state); + void on_message(const std::shared_ptr &_request); + void run(); + +private: + std::shared_ptr app_; + bool is_registered_; + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + big_payload_test::test_mode test_mode_; + std::uint32_t number_of_received_messages_; + std::thread offer_thread_; + std::uint32_t expected_messages_; + vsomeip::service_t service_id_; + std::queue> incoming_requests_; +}; + +#endif /* BIGPAYLOADTESTSERVICE_HPP_ */ diff --git a/test/network_tests/big_payload_tests/big_payload_test_service_local_start.sh b/test/network_tests/big_payload_tests/big_payload_test_service_local_start.sh new file mode 100755 index 0000000..299af82 --- /dev/null +++ b/test/network_tests/big_payload_tests/big_payload_test_service_local_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Start the service +export VSOMEIP_APPLICATION_NAME=big_payload_test_service +export VSOMEIP_CONFIGURATION=big_payload_test_local.json +./big_payload_test_service diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client.json.in new file mode 100644 index 0000000..41c88f5 --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client.json.in @@ -0,0 +1,64 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"error", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatchers" : "0" + }, + { + "name":"big_payload_test_client", + "id":"0x1344", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678" + } + ], + "payload-sizes": + [ + { + "unicast":"127.0.0.1", + "ports": + [ + { + "port":"30509", + "max-payload-size":"614400" + } + ] + } + ], + "routing": + { + "host" : + { + "name" : "big_payload_test_client", + "unicast" : "@TEST_IP_MASTER@", + "port" : "31490" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} + diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_limited.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_limited.json.in new file mode 100644 index 0000000..cd52a3c --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_limited.json.in @@ -0,0 +1,52 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatchers" : "0" + }, + { + "name":"big_payload_test_client", + "id":"0x1344", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678" + } + ], + "max-payload-size-local" : "614400", + "routing": + { + "host" : + { + "name" : "big_payload_test_client", + "unicast" : "@TEST_IP_MASTER@", + "port" : "31490" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} + diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_queue_limited.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_queue_limited.json.in new file mode 100644 index 0000000..b233f74 --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_queue_limited.json.in @@ -0,0 +1,52 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatchers" : "0" + }, + { + "name":"big_payload_test_client", + "id":"0x1344", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678" + } + ], + "endpoint-queue-limit-local" : "614431", + "routing": + { + "host" : + { + "name" : "big_payload_test_client", + "unicast" : "@TEST_IP_MASTER@", + "port" : "31490" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} + diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_random.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_random.json.in new file mode 100644 index 0000000..521f46e --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_client_random.json.in @@ -0,0 +1,52 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatchers" : "0" + }, + { + "name":"big_payload_test_client", + "id":"0x1344", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678" + } + ], + "buffer-shrink-threshold" : "2", + "routing": + { + "host" : + { + "name" : "big_payload_test_client", + "unicast" : "@TEST_IP_MASTER@", + "port" : "31490" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} + diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service.json.in new file mode 100644 index 0000000..6f64035 --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service.json.in @@ -0,0 +1,68 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatchers" : "0" + }, + { + "name":"big_payload_test_client", + "id":"0x1344", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678" + } + ], + "payload-sizes": + [ + { + "unicast":"127.0.0.1", + "ports": + [ + { + "port":"30509", + "max-payload-size":"614400" + } + ] + } + ], + "routing": + { + "host" : + { + "name" : "big_payload_test_client", + "unicast" : "@TEST_IP_MASTER@", + "port" : "31490" + }, + "guests" : + { + "unicast" : "@TEST_IP_SLAVE@" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} + diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_limited.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_limited.json.in new file mode 100644 index 0000000..2373eaa --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_limited.json.in @@ -0,0 +1,56 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatchers" : "0" + }, + { + "name":"big_payload_test_client", + "id":"0x1344", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678" + } + ], + "max-payload-size-local" : "614400", + "routing": + { + "host" : + { + "name" : "big_payload_test_client", + "unicast" : "@TEST_IP_MASTER@", + "port" : "31490" + }, + "guests" : + { + "unicast" : "@TEST_IP_SLAVE@" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} + diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_queue_limited.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_queue_limited.json.in new file mode 100644 index 0000000..eac3dce --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_queue_limited.json.in @@ -0,0 +1,56 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatchers" : "0" + }, + { + "name":"big_payload_test_client", + "id":"0x1344", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678" + } + ], + "endpoint-queue-limit-local" : "614431", + "routing": + { + "host" : + { + "name" : "big_payload_test_client", + "unicast" : "@TEST_IP_MASTER@", + "port" : "31490" + }, + "guests" : + { + "unicast" : "@TEST_IP_SLAVE@" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} + diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_random.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_random.json.in new file mode 100644 index 0000000..c66e09f --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_local_tcp_service_random.json.in @@ -0,0 +1,56 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatchers" : "0" + }, + { + "name":"big_payload_test_client", + "id":"0x1344", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678" + } + ], + "buffer-shrink-threshold" : "2", + "routing": + { + "host" : + { + "name" : "big_payload_test_client", + "unicast" : "@TEST_IP_MASTER@", + "port" : "31490" + }, + "guests" : + { + "unicast" : "@TEST_IP_SLAVE@" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} + diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client.json.in new file mode 100644 index 0000000..0f23a10 --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client.json.in @@ -0,0 +1,43 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "netmask":"255.255.255.0", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"true", + "path":"/var/log/vsomeip.log" + }, + "dlt":"true" + }, + "applications": + [ + { + "name":"big_payload_test_client", + "id":"0x1343" + } + ], + "payload-sizes": + [ + { + "unicast":"@TEST_IP_SLAVE@", + "ports": + [ + { + "port":"30509", + "max-payload-size":"614400" + } + ] + } + ], + "routing":"big_payload_test_client", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_limited_general.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_limited_general.json.in new file mode 100644 index 0000000..f28efc8 --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_limited_general.json.in @@ -0,0 +1,31 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "netmask":"255.255.255.0", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"true", + "path":"/var/log/vsomeip.log" + }, + "dlt":"true" + }, + "applications": + [ + { + "name":"big_payload_test_client", + "id":"0x1343" + } + ], + "max-payload-size-reliable":"614400", + "routing":"big_payload_test_client", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_general.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_general.json.in new file mode 100644 index 0000000..a193ab8 --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_general.json.in @@ -0,0 +1,31 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "netmask":"255.255.255.0", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"true", + "path":"/var/log/vsomeip.log" + }, + "dlt":"true" + }, + "applications": + [ + { + "name":"big_payload_test_client", + "id":"0x1343" + } + ], + "endpoint-queue-limit-external" : "614416", + "routing":"big_payload_test_client", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_specific.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_specific.json.in new file mode 100644 index 0000000..79f3486 --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_queue_limited_specific.json.in @@ -0,0 +1,43 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "netmask":"255.255.255.0", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"true", + "path":"/var/log/vsomeip.log" + }, + "dlt":"true" + }, + "applications": + [ + { + "name":"big_payload_test_client", + "id":"0x1343" + } + ], + "endpoint-queue-limits" : + [ + { + "unicast":"@TEST_IP_SLAVE@", + "ports": + [ + { + "port":"30509", + "queue-size-limit":"614416" + } + ] + } + ], + "routing":"big_payload_test_client", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_random.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_random.json.in new file mode 100644 index 0000000..85cf393 --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_client_random.json.in @@ -0,0 +1,32 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "netmask":"255.255.255.0", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"true", + "path":"/var/log/vsomeip.log" + }, + "dlt":"true" + }, + "applications": + [ + { + "name":"big_payload_test_client", + "id":"0x1343", + "max_dispatch_time" : "5000" + } + ], + "buffer-shrink-threshold" : "2", + "routing":"big_payload_test_client", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service.json.in new file mode 100644 index 0000000..08149bb --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service.json.in @@ -0,0 +1,81 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"debug", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1235", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1236", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1237", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + } + ], + "payload-sizes": + [ + { + "unicast":"@TEST_IP_SLAVE@", + "ports": + [ + { + "port":"30509", + "max-payload-size":"614400" + } + ] + } + ], + "routing":"big_payload_test_service", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_limited_general.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_limited_general.json.in new file mode 100644 index 0000000..f8414f3 --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_limited_general.json.in @@ -0,0 +1,69 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"debug", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1235", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1236", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1237", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + } + ], + "max-payload-size-reliable":"614400", + "routing":"big_payload_test_service", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_general.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_general.json.in new file mode 100644 index 0000000..ad5b28c --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_general.json.in @@ -0,0 +1,87 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"debug", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1235", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1236", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1237", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1238", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1239", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + } + ], + "endpoint-queue-limit-external" : "614416", + "routing":"big_payload_test_service", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_specific.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_specific.json.in new file mode 100644 index 0000000..87bcdaa --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_queue_limited_specific.json.in @@ -0,0 +1,99 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"debug", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1235", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1236", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1237", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1238", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1239", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + } + ], + "endpoint-queue-limits" : + [ + { + "unicast":"@TEST_IP_SLAVE@", + "ports": + [ + { + "port":"30509", + "queue-size-limit":"614416" + } + ] + } + ], + "routing":"big_payload_test_service", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_random.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_random.json.in new file mode 100644 index 0000000..d583fd1 --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_tcp_service_random.json.in @@ -0,0 +1,70 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"debug", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatch_time" : "5000" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1235", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1236", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1237", + "instance":"0x01", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"false" + } + } + ], + "buffer-shrink-threshold" : "2", + "routing":"big_payload_test_service", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_udp_client.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_udp_client.json.in new file mode 100644 index 0000000..5a7ee36 --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_udp_client.json.in @@ -0,0 +1,44 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "netmask":"255.255.255.0", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"true", + "path":"/var/log/vsomeip.log" + }, + "dlt":"true" + }, + "applications": + [ + { + "name":"big_payload_test_client", + "id":"0x1343", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1240", + "instance":"0x01", + "unicast":"@TEST_IP_SLAVE@", + "unreliable": "30509", + "someip-tp" : { + "client-to-service" : [ "0x8421" ] + } + } + ], + "max-payload-size-reliable":"614400", + "routing":"big_payload_test_client", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/big_payload_tests/conf/big_payload_test_udp_service.json.in b/test/network_tests/big_payload_tests/conf/big_payload_test_udp_service.json.in new file mode 100644 index 0000000..7f71a05 --- /dev/null +++ b/test/network_tests/big_payload_tests/conf/big_payload_test_udp_service.json.in @@ -0,0 +1,41 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"debug", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"big_payload_test_service", + "id":"0x1277", + "max_dispatchers" : "0" + } + ], + "services": + [ + { + "service":"0x1240", + "instance":"0x01", + "unreliable": "30509", + "someip-tp" : { + "service-to-client" : [ "0x8421" ] + } + } + ], + "routing":"big_payload_test_service", + "service-discovery": + { + "enable":"true", + "multicast":"224.244.224.245", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/client_id_tests/client_id_test_globals.hpp b/test/network_tests/client_id_tests/client_id_test_globals.hpp new file mode 100644 index 0000000..e4b2cb8 --- /dev/null +++ b/test/network_tests/client_id_tests/client_id_test_globals.hpp @@ -0,0 +1,34 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef CLIENT_ID_TEST_CLIENT_ID_TEST_GLOBALS_HPP_ +#define CLIENT_ID_TEST_CLIENT_ID_TEST_GLOBALS_HPP_ + +namespace client_id_test { + +struct service_info { + vsomeip::service_t service_id; + vsomeip::instance_t instance_id; + vsomeip::method_t method_id; + vsomeip::client_t offering_client; +}; + +static constexpr std::array service_infos = {{ + // placeholder to be consistent w/ client ids, service ids, app names + { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }, + // node 1 + { 0x1000, 0x1, 0x1111, 0x1111 }, + { 0x2000, 0x1, 0x2222, 0x2222}, + { 0x3000, 0x1, 0x3333, 0x3333}, + // node 2 + { 0x4000, 0x1, 0x4444, 0x4444 }, + { 0x5000, 0x1, 0x5555, 0x5555 }, + { 0x6000, 0x1, 0x6666, 0x6666 } +}}; + +static constexpr int messages_to_send = 10; +} + +#endif /* CLIENT_ID_TEST_CLIENT_ID_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/client_id_tests/client_id_test_master_starter.sh b/test/network_tests/client_id_tests/client_id_test_master_starter.sh new file mode 100755 index 0000000..5495c44 --- /dev/null +++ b/test/network_tests/client_id_tests/client_id_test_master_starter.sh @@ -0,0 +1,80 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +if [ $# -lt 1 ] +then + echo "Please pass a json file to this script." + echo "For example: $0 client_id_test_diff_client_ids_diff_ports_master.json" + exit 1 +fi + +MASTER_JSON_FILE=$1 +CLIENT_JSON_FILE=${MASTER_JSON_FILE/master/slave} + +FAIL=0 + +# Start the services +export VSOMEIP_APPLICATION_NAME=client_id_test_service_one +export VSOMEIP_CONFIGURATION=$1 +./client_id_test_service 1 & +CLIENT_ID_PIDS[1]=$! + +export VSOMEIP_APPLICATION_NAME=client_id_test_service_two +export VSOMEIP_CONFIGURATION=$1 +./client_id_test_service 2 & +CLIENT_ID_PIDS[2]=$! + +export VSOMEIP_APPLICATION_NAME=client_id_test_service_three +export VSOMEIP_CONFIGURATION=$1 +./client_id_test_service 3 & +CLIENT_ID_PIDS[3]=$! + +sleep 1 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting client id test on slave LXC" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./client_id_test_slave_starter.sh $CLIENT_JSON_FILE\"" & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./client_id_test_slave_starter.sh $CLIENT_JSON_FILE" & +else +cat < +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "client_id_test_globals.hpp" + + +class client_id_test_service { +public: + client_id_test_service(struct client_id_test::service_info _service_info) : + service_info_(_service_info), + app_(vsomeip::runtime::get()->create_application()), + blocked_(false), + offer_thread_(std::bind(&client_id_test_service::run, this)), + stopped_(false), + stop_thread_(std::bind(&client_id_test_service::wait_for_stop, this)) { + if (!app_->init()) { + offer_thread_.detach(); + stop_thread_.detach(); + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&client_id_test_service::on_state, this, + std::placeholders::_1)); + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.method_id, + std::bind(&client_id_test_service::on_request, this, + std::placeholders::_1)); + app_->register_message_handler(vsomeip::ANY_SERVICE, + service_info_.instance_id, vsomeip::ANY_METHOD, + std::bind(&client_id_test_service::on_response, this, + std::placeholders::_1)); + + for(const auto& i : client_id_test::service_infos) { + if ((i.service_id == service_info_.service_id + && i.instance_id == service_info_.instance_id) + || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { + continue; + } + app_->request_service(i.service_id, i.instance_id); + app_->register_availability_handler(i.service_id, i.instance_id, + std::bind(&client_id_test_service::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; + other_services_received_response_[std::make_pair(i.service_id, i.method_id)] = 0; + other_services_received_request_[i.offering_client] = 0; + } + + app_->start(); + } + + ~client_id_test_service() { + if (offer_thread_.joinable()) { + offer_thread_.join(); + } + if (stop_thread_.joinable()) { + stop_thread_.join(); + } + } + + void offer() { + app_->offer_service(service_info_.service_id, service_info_.instance_id); + } + + void stop_offer() { + app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + if(_is_available) { + VSOMEIP_INFO + << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Service [" + << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance + << "] is " + << (_is_available ? "available." : "NOT available."); + + auto its_service = other_services_available_.find(std::make_pair(_service, _instance)); + if(its_service != other_services_available_.end()) { + its_service->second = true; + } + + if(std::all_of(other_services_available_.cbegin(), + other_services_available_.cend(), + [](const std::map, bool>::value_type& v) { + return v.second;})) { + std::lock_guard its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); + } + } + } + + void on_request(const std::shared_ptr &_message) { + if(_message->get_message_type() == vsomeip::message_type_e::MT_REQUEST) { + VSOMEIP_DEBUG + << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id + << "] Received a request with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_session() << "]"; + std::shared_ptr its_response = vsomeip::runtime::get() + ->create_response(_message); + app_->send(its_response); + + other_services_received_request_[_message->get_client()]++; + if(all_responses_and_requests_received()) { + std::lock_guard its_lock(stop_mutex_); + stopped_ = true; + stop_condition_.notify_one(); + } + } + } + + void on_response(const std::shared_ptr &_message) { + if(_message->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + VSOMEIP_DEBUG + << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id + << "] Received a response with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_session() << "] from Service/Method [" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_service() << "/" << std::setw(4) << std::setfill('0') + << std::hex << _message->get_method() <<"]"; + other_services_received_response_[std::make_pair(_message->get_service(), + _message->get_method())]++; + + if(all_responses_and_requests_received()) { + std::lock_guard its_lock(stop_mutex_); + stopped_ = true; + stop_condition_.notify_one(); + } + } + } + + bool all_responses_and_requests_received() { + const bool responses = std::all_of( + other_services_received_response_.cbegin(), + other_services_received_response_.cend(), + [](const std::map, std::uint32_t>::value_type& v) + { return v.second == client_id_test::messages_to_send;}); + const bool requests = std::all_of( + other_services_received_request_.cbegin(), + other_services_received_request_.cend(), + [](const std::map::value_type& v) + { return v.second == client_id_test::messages_to_send;}); + return (responses && requests); + } + + void run() { + std::unique_lock its_lock(mutex_); + while (!blocked_) { + condition_.wait(its_lock); + } + blocked_ = false; + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + + + while (!blocked_) { + condition_.wait(its_lock); + } + blocked_ = false; + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Sending"; + // send a message to all other services + for (int var = 0; var < client_id_test::messages_to_send; ++var) { + for(const client_id_test::service_info& i: client_id_test::service_infos) { + if ((i.service_id == service_info_.service_id + && i.instance_id == service_info_.instance_id) + || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { + continue; + } + std::shared_ptr msg = vsomeip::runtime::get()->create_request(); + msg->set_service(i.service_id); + msg->set_instance(i.instance_id); + msg->set_method(i.method_id); + app_->send(msg); + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') + << std::hex << service_info_.service_id + << "] Sending a request to Service/Method [" + << std::setw(4) << std::setfill('0') << std::hex + << i.service_id << "/" << std::setw(4) << std::setfill('0') + << std::hex << i.instance_id <<"]"; + } + } + + while (!blocked_) { + condition_.wait(its_lock); + } + blocked_ = false; + } + + void wait_for_stop() { + std::unique_lock its_lock(stop_mutex_); + while (!stopped_) { + stop_condition_.wait(its_lock); + } + VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id + << "] Received responses and requests from all other services, going down"; + + // let offer thread exit + { + std::lock_guard its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); + } + + std::this_thread::sleep_for(std::chrono::seconds(3)); + app_->clear_all_handler(); + app_->stop(); + } + +private: + client_id_test::service_info service_info_; + std::shared_ptr app_; + std::map, bool> other_services_available_; + std::map, std::uint32_t> other_services_received_response_; + std::map other_services_received_request_; + + bool blocked_; + std::mutex mutex_; + std::condition_variable condition_; + std::thread offer_thread_; + + bool stopped_; + std::mutex stop_mutex_; + std::condition_variable stop_condition_; + std::thread stop_thread_; +}; + +static int service_number; + +TEST(someip_client_id_test, send_ten_messages_to_service) +{ + client_id_test_service its_sample( + client_id_test::service_infos[static_cast(service_number)]); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a service number, like: " << argv[0] << " 2" << std::endl; + std::cerr << "Valid service numbers are in the range of [1,6]" << std::endl; + return 1; + } + service_number = std::stoi(std::string(argv[1]), nullptr); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/client_id_tests/client_id_test_slave_starter.sh b/test/network_tests/client_id_tests/client_id_test_slave_starter.sh new file mode 100755 index 0000000..4553521 --- /dev/null +++ b/test/network_tests/client_id_tests/client_id_test_slave_starter.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +if [ $# -lt 1 ] +then + echo "Please pass a json file to this script." + echo "For example: $0 client_id_test_diff_client_ids_diff_ports_slave.json" + exit 1 +fi + +FAIL=0 + +# Start the services +export VSOMEIP_APPLICATION_NAME=client_id_test_service_four +export VSOMEIP_CONFIGURATION=$1 +./client_id_test_service 4 & + +export VSOMEIP_APPLICATION_NAME=client_id_test_service_five +export VSOMEIP_CONFIGURATION=$1 +./client_id_test_service 5 & + +export VSOMEIP_APPLICATION_NAME=client_id_test_service_six +export VSOMEIP_CONFIGURATION=$1 +./client_id_test_service 6 & + + +# Wait until all applications are finished +for job in $(jobs -p) +do + # Fail gets incremented if one of the binaries exits + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +# Check if both exited successfully +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/client_id_tests/client_id_test_utility.cpp b/test/network_tests/client_id_tests/client_id_test_utility.cpp new file mode 100644 index 0000000..a74f922 --- /dev/null +++ b/test/network_tests/client_id_tests/client_id_test_utility.cpp @@ -0,0 +1,608 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include +#include +#include + +#include +#include "../../implementation/utility/include/utility.hpp" +#include "../../implementation/configuration/include/configuration.hpp" +#include "../../implementation/configuration/include/configuration_plugin.hpp" +#include "../../implementation/plugin/include/plugin_manager_impl.hpp" + +using namespace vsomeip; + +static const std::string APPLICATION_NAME_ROUTING_MANAGER = "routingmanagerd"; + +static const std::string APPLICATION_NAME_NOT_PREDEFINED = "test-application-name"; + +vsomeip::client_t CLIENT_ID_ROUTING_MANAGER = 0xFFFF; + +static const std::string APPLICATION_IN_NAME = "client_id_test_utility_service_in"; +static vsomeip::client_t APPLICATION_IN_CLIENT_ID = 0xFFFF; + +static const std::string APPLICATION_IN_NAME_TWO = "client_id_test_utility_service_in_two"; +static vsomeip::client_t APPLICATION_IN_CLIENT_ID_TWO = 0xFFFF; + +static const std::string APPLICATION_OUT_LOW_NAME = "client_id_test_utility_service_out_low"; +static const vsomeip::client_t APPLICATION_OUT_LOW_CLIENT_ID = 0x5911; + +static const std::string APPLICATION_OUT_HIGH_NAME = "client_id_test_utility_service_out_high"; +static const vsomeip::client_t APPLICATION_OUT_HIGH_CLIENT_ID = 0x7411; + +class client_id_utility_test: public ::testing::Test { +public: + client_id_utility_test() : + client_id_routing_manager_(0x0), + diagnosis_(0x0), + diagnosis_mask_(0xFF00), + client_id_base_(0x0) { + + std::shared_ptr its_configuration; + auto its_plugin = vsomeip::plugin_manager::get()->get_plugin( + vsomeip::plugin_type_e::CONFIGURATION_PLUGIN, VSOMEIP_CFG_LIBRARY); + if (its_plugin) { + auto its_config_plugin = std::dynamic_pointer_cast(its_plugin); + if (its_config_plugin) { + configuration_ = its_config_plugin->get_configuration(APPLICATION_NAME_ROUTING_MANAGER, ""); + } + } + } +protected: + virtual void SetUp() { + ASSERT_TRUE(static_cast(configuration_)); + configuration_->load(APPLICATION_NAME_ROUTING_MANAGER); + diagnosis_mask_ = configuration_->get_diagnosis_mask(); + diagnosis_ = configuration_->get_diagnosis_address(); + + // calculate all client IDs based on mask + client_id_base_ = static_cast(diagnosis_ << 8); + CLIENT_ID_ROUTING_MANAGER = + static_cast((configuration_->get_diagnosis_address() + << 8) & configuration_->get_diagnosis_mask()); + APPLICATION_IN_CLIENT_ID = static_cast(client_id_base_ | 0x11); + APPLICATION_IN_CLIENT_ID_TWO = static_cast(client_id_base_ | 0x12); + + app_ = vsomeip::runtime::get()->create_application(APPLICATION_NAME_ROUTING_MANAGER); + EXPECT_TRUE(app_->init()); + EXPECT_EQ(CLIENT_ID_ROUTING_MANAGER, app_->get_client()); + + rm_impl_thread_ = std::thread([&](){ + app_->start(); + }); + // ensure clean preconditions + utility::reset_client_ids(configuration_->get_network()); + + // required as there are two static versions of the utility class in this + // test, one in the test itself and one in libvsomeip... + client_id_routing_manager_ = utility::request_client_id( + configuration_, APPLICATION_NAME_ROUTING_MANAGER, static_cast( + (configuration_->get_diagnosis_address() << 8) + & configuration_->get_diagnosis_mask())); + EXPECT_EQ(CLIENT_ID_ROUTING_MANAGER, client_id_routing_manager_); + } + + virtual void TearDown() { + app_->stop(); + if (rm_impl_thread_.joinable()) { + rm_impl_thread_.join(); + } + app_.reset(); + utility::release_client_id(configuration_->get_network(), client_id_routing_manager_); + } + +protected: + std::shared_ptr configuration_; + vsomeip::client_t client_id_routing_manager_; + std::uint16_t diagnosis_; + std::uint16_t diagnosis_mask_; + client_t client_id_base_; + std::shared_ptr app_; + std::thread rm_impl_thread_; +}; + +class app_wrapper { +public: + app_wrapper(const std::string& _name) : + app_(vsomeip::runtime::get()->create_application(_name)), + client_(VSOMEIP_CLIENT_UNSET) { + EXPECT_TRUE(app_->init()); + app_->register_state_handler( + std::bind(&app_wrapper::on_state, this, std::placeholders::_1)); + app_thread_ = std::thread([&](){ app_->start(); }); + } + + ~app_wrapper() { + app_->stop(); + if (app_thread_.joinable()) { + app_thread_.join(); + } + app_.reset(); + } + + void on_state(const vsomeip::state_type_e& _state) { + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + client_ = app_->get_client(); + registered_.set_value(); + } + }; + + client_t get_client() { + if (std::future_status::timeout + == registered_.get_future().wait_for( + std::chrono::seconds(11))) { + ADD_FAILURE()<< __LINE__ << " application wasn't registered within time"; + } + return client_; + } + + std::shared_ptr get_app() { + return app_; + } + +private: + std::shared_ptr app_; + std::promise registered_; + std::thread app_thread_; + vsomeip::client_t client_; +}; + +TEST_F(client_id_utility_test, request_release_client_id) { + app_wrapper app(APPLICATION_NAME_NOT_PREDEFINED); + EXPECT_EQ(client_id_base_ | 0x1, app.get_client()); +} + +TEST_F(client_id_utility_test, request_client_id_twice) { + app_wrapper app(APPLICATION_NAME_NOT_PREDEFINED); + EXPECT_EQ(client_id_base_ | 0x1, app.get_client()); + + app_wrapper app2(APPLICATION_NAME_NOT_PREDEFINED); + EXPECT_EQ(client_id_base_ | 0x2, app2.get_client()); +} + +TEST_F(client_id_utility_test, ensure_sequential_ascending_client_id_allocation) { + app_wrapper app(APPLICATION_NAME_NOT_PREDEFINED); + EXPECT_EQ(client_id_base_ | 0x1, app.get_client()); + + auto app2 = std::make_shared(APPLICATION_NAME_NOT_PREDEFINED); + client_t app2_client = app2->get_client(); + EXPECT_EQ(client_id_base_ | 0x2, app2_client); + + app2.reset(); + + auto app3 = std::make_shared(APPLICATION_NAME_NOT_PREDEFINED); + client_t app3_client = app3->get_client(); + EXPECT_EQ(client_id_base_ | 0x3, app3_client); + + EXPECT_GT(app3_client, app2_client); + +} + +TEST_F(client_id_utility_test, ensure_preconfigured_client_ids_not_used_for_autoconfig) +{ + // request client ids until 10 over the preconfigured one + const std::uint16_t limit = + static_cast((APPLICATION_IN_CLIENT_ID + & ~diagnosis_mask_) + std::uint16_t(10)); + + std::vector> its_apps; + its_apps.reserve(limit); + + for (int i = 0; i < limit; i++ ) { + its_apps.emplace_back( + std::make_shared(APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i))); + } + for (const auto& a : its_apps) { + EXPECT_NE(APPLICATION_IN_CLIENT_ID, a->get_client()); + } + its_apps.clear(); +} + +TEST_F(client_id_utility_test, + request_predefined_client_id_in_diagnosis_range) { + auto app1 = std::make_shared(APPLICATION_IN_NAME); + EXPECT_EQ(APPLICATION_IN_CLIENT_ID, app1->get_client()); +} + +TEST_F(client_id_utility_test, + request_predefined_client_id_in_diagnosis_range_twice) { + auto app1 = std::make_shared(APPLICATION_IN_NAME); + EXPECT_EQ(APPLICATION_IN_CLIENT_ID, app1->get_client()); + + // preconfigured is already taken -> autogenerated ID should be returned + auto app2 = std::make_shared(APPLICATION_IN_NAME); + EXPECT_EQ(client_id_base_ | 0x1, app2->get_client()); +} + +TEST_F(client_id_utility_test, + request_predefined_client_id_outside_diagnosis_range_high) { + auto app1 = std::make_shared(APPLICATION_OUT_HIGH_NAME); + // we should get the client ID defined in the json file + EXPECT_EQ(APPLICATION_OUT_HIGH_CLIENT_ID, app1->get_client()); +} + +TEST_F(client_id_utility_test, + request_client_id_with_predefined_app_name_outside_diagnosis_range_high_multiple) { + + auto app1 = std::make_shared(APPLICATION_OUT_HIGH_NAME); + // we should get the client ID defined in the json file + EXPECT_EQ(APPLICATION_OUT_HIGH_CLIENT_ID, app1->get_client()); + + // preconfigured is already taken -> autogenerated ID should be returned + auto app2 = std::make_shared(APPLICATION_OUT_HIGH_NAME); + EXPECT_EQ(client_id_base_ | 0x1, app2->get_client()); + + auto app3 = std::make_shared(APPLICATION_OUT_HIGH_NAME); + EXPECT_EQ(client_id_base_ | 0x2, app3->get_client()); +} + +TEST_F(client_id_utility_test, + request_predefined_client_id_outside_diagnosis_range_low) { + auto app1 = std::make_shared(APPLICATION_OUT_LOW_NAME); + // we should get the client ID defined in the json file + EXPECT_EQ(APPLICATION_OUT_LOW_CLIENT_ID, app1->get_client()); +} + +TEST_F(client_id_utility_test, + request_predefined_client_id_outside_diagnosis_range_low_multiple) { + auto app1 = std::make_shared(APPLICATION_OUT_LOW_NAME); + // we should get the client ID defined in the json file + EXPECT_EQ(APPLICATION_OUT_LOW_CLIENT_ID, app1->get_client()); + + // preconfigured is already taken -> autogenerated ID should be returned + auto app2 = std::make_shared(APPLICATION_OUT_LOW_NAME); + EXPECT_EQ(client_id_base_ | 0x1, app2->get_client()); + + auto app3 = std::make_shared(APPLICATION_OUT_LOW_NAME); + EXPECT_EQ(client_id_base_ | 0x2, app3->get_client()); +} + +TEST_F(client_id_utility_test, + ensure_preconfigured_client_ids_in_diagnosis_range_dont_influence_autoconfig_client_ids) +{ + auto app0 = std::make_shared(APPLICATION_NAME_NOT_PREDEFINED); + EXPECT_EQ(client_id_base_ | 0x1, app0->get_client()); + + auto app1 = std::make_shared(APPLICATION_IN_NAME); + EXPECT_EQ(APPLICATION_IN_CLIENT_ID, app1->get_client()); + + auto app2 = std::make_shared(APPLICATION_IN_NAME_TWO); + EXPECT_EQ(APPLICATION_IN_CLIENT_ID_TWO, app2->get_client()); + + auto app3 = std::make_shared(APPLICATION_NAME_NOT_PREDEFINED); + EXPECT_EQ(client_id_base_ | 0x2, app3->get_client()); + + auto app4 = std::make_shared(APPLICATION_NAME_NOT_PREDEFINED); + EXPECT_EQ(client_id_base_ | 0x3, app4->get_client()); +} + +TEST_F(client_id_utility_test, exhaust_client_id_range_sequential) { + std::vector its_clients; + std::uint16_t its_max_clients(0); + for (int var = 0; var < __builtin_popcount(static_cast(~diagnosis_mask_)); ++var) { + its_max_clients = static_cast(its_max_clients | (1 << var)); + } + // -2 as two predefined client IDs are present in the json file which + // aren't assigned via autoconfiguration + const std::uint16_t max_allowed_clients = static_cast(its_max_clients - 2u); + + // acquire maximum amount of client IDs + for (int var = 0; var < 2; ++var) { + for (std::uint16_t i = 0; i < max_allowed_clients; i++) { + const vsomeip::client_t its_client = + vsomeip::utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i), + VSOMEIP_CLIENT_UNSET); + if (its_client != VSOMEIP_CLIENT_UNSET) { + if (i > 0) { + EXPECT_LT(its_clients.back(), its_client); + } + its_clients.push_back(its_client); + } else { + ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " + << static_cast(i); + } + } + // check limit is reached + EXPECT_EQ(VSOMEIP_CLIENT_UNSET, vsomeip::utility::request_client_id( + configuration_, APPLICATION_NAME_NOT_PREDEFINED + "max", + VSOMEIP_CLIENT_UNSET)); + for (const auto c : its_clients) { + utility::release_client_id(configuration_->get_network(), c); + } + } + } + +TEST_F(client_id_utility_test, exhaust_client_id_range_fragmented) { + std::vector its_clients; + + // -2 as two predefined client IDs are present in the json file which + // aren't assigned via autoconfiguration + std::uint16_t its_max_clients(0); + for (int var = 0; var < __builtin_popcount(static_cast(~diagnosis_mask_)); ++var) { + its_max_clients = static_cast(its_max_clients | (1 << var)); + } + const std::uint16_t max_allowed_clients = static_cast(its_max_clients - 2u); + + for (int var = 0; var < 2; ++var) { + // acquire maximum amount of client IDs + for (std::uint16_t i = 0; i < max_allowed_clients; i++) { + const vsomeip::client_t its_client = + vsomeip::utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i), + VSOMEIP_CLIENT_UNSET); + if (its_client != VSOMEIP_CLIENT_UNSET) { + if ((var == 0 && i > 0) || + (var == 1 && i > 1) // special case as in the 1st run the last assigned client ID was 63fe + // due to the releases. In the 2nd run the first client ID therefore will be 63ff + ) { + EXPECT_LT(its_clients.back(), its_client); + } + its_clients.push_back(its_client); + } else { + ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " + << static_cast(i); + } + } + + // check limit is reached + EXPECT_EQ(VSOMEIP_CLIENT_UNSET, vsomeip::utility::request_client_id( + configuration_, APPLICATION_NAME_NOT_PREDEFINED + "max", + VSOMEIP_CLIENT_UNSET)); + + // release every second requested client ID + std::vector its_released_client_ids; + for (size_t i = 0; i < its_clients.size(); i++ ) { + if (i % 2) { + its_released_client_ids.push_back(its_clients[i]); + utility::release_client_id(configuration_->get_network(), its_clients[i]); + } + } + for (const client_t c : its_released_client_ids) { + for (auto it = its_clients.begin(); it != its_clients.end(); ) { + if (*it == c) { + it = its_clients.erase(it); + } else { + ++it; + } + } + } + + // acquire client IDs up to the maximum allowed amount again + for (std::uint16_t i = 0; i < its_released_client_ids.size(); i++) { + const vsomeip::client_t its_client = + vsomeip::utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i), + VSOMEIP_CLIENT_UNSET); + if (its_client != VSOMEIP_CLIENT_UNSET) { + if (i > 0) { + EXPECT_LT(its_clients.back(), its_client); + } + its_clients.push_back(its_client); + } else { + ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " + << static_cast(i); + } + } + + // check limit is reached + EXPECT_EQ(VSOMEIP_CLIENT_UNSET, vsomeip::utility::request_client_id( + configuration_, APPLICATION_NAME_NOT_PREDEFINED + "max2", + VSOMEIP_CLIENT_UNSET)); + + // release all + for (const auto c : its_clients) { + utility::release_client_id(configuration_->get_network(), c); + } + its_clients.clear(); + } +} + +/* + * @test Check that the autoconfigured client IDs continue to increase even if + * some client IDs at the beginning of the range are already released again + */ +TEST_F(client_id_utility_test, exhaust_client_id_range_fragmented_extended) { + std::vector its_client_ids; + + // -1 for the routing manager, -2 as two predefined client IDs are present + // in the json file which aren't assigned via autoconfiguration + std::uint16_t its_max_clients(0); + for (int var = 0; var < __builtin_popcount(static_cast(~diagnosis_mask_)); ++var) { + its_max_clients = static_cast(its_max_clients | (1 << var)); + } + const std::uint16_t its_diagnosis_mask = configuration_->get_diagnosis_mask(); + const std::uint16_t its_client_mask = static_cast(~its_diagnosis_mask); + const client_t its_masked_diagnosis_address = static_cast( + (configuration_->get_diagnosis_address() << 8) & its_diagnosis_mask); + const client_t its_biggest_client = its_masked_diagnosis_address | its_client_mask; + + const std::uint16_t max_possible_clients = its_max_clients; + const std::uint16_t intermediate_release = 3; + const std::uint16_t max_allowed_clients = static_cast(max_possible_clients - 2u); + + // acquire (almost) maximum amount of client IDs + for (std::uint16_t i = 0; i < max_allowed_clients - intermediate_release; i++) { + client_t its_client_id = utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i), + VSOMEIP_CLIENT_UNSET); + EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); + if (its_client_id != VSOMEIP_CLIENT_UNSET) { + if (i > 0) { + EXPECT_LT(its_client_ids.back(), its_client_id); + } + its_client_ids.push_back(its_client_id); + } else { + ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " + << static_cast(i); + } + } + + // release the first intermediate_release client IDs again + std::vector its_intermediate_released_client_ids; + for (size_t i = 0; i < intermediate_release; i++ ) { + its_intermediate_released_client_ids.push_back(its_client_ids[i]); + utility::release_client_id(configuration_->get_network(), its_client_ids[i]); + its_client_ids.erase(its_client_ids.begin() + i); + } + + // acquire some more client IDs, these should be bigger than the already acquired + for (std::uint16_t i = 0; i < intermediate_release; i++) { + client_t its_client_id = utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i) + + "intermediate", + VSOMEIP_CLIENT_UNSET); + EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); + if (its_client_id != VSOMEIP_CLIENT_UNSET) { + EXPECT_LT(its_client_ids.back(), its_client_id); + its_client_ids.push_back(its_client_id); + } else { + ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " + << static_cast(i); + } + } + + // check correct wrap around of client IDs + for (std::uint16_t i = 0; i < intermediate_release; i++) { + client_t its_client_id = utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i), + VSOMEIP_CLIENT_UNSET); + EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); + if (its_client_id != VSOMEIP_CLIENT_UNSET) { + if (i == 0) { + EXPECT_GT(its_client_ids.back(), its_client_id); + } else { + EXPECT_LT(its_client_ids.back(), its_client_id); + } + its_client_ids.push_back(its_client_id); + } else { + ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " + << static_cast(i); + } + } + + // check limit is reached + client_t its_illegal_client_id = utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); + EXPECT_EQ(VSOMEIP_CLIENT_UNSET, its_illegal_client_id); + + // release every second requested client ID + std::vector its_released_client_ids; + for (size_t i = 0; i < its_client_ids.size(); i++ ) { + if (i % 2) { + its_released_client_ids.push_back(its_client_ids[i]); + utility::release_client_id(configuration_->get_network(), its_client_ids[i]); + } + } + for (const client_t c : its_released_client_ids) { + for (auto it = its_client_ids.begin(); it != its_client_ids.end(); ) { + if (*it == c) { + it = its_client_ids.erase(it); + } else { + ++it; + } + } + } + + // acquire client IDs up to the maximum allowed amount again + for (std::uint16_t i = 0; i < its_released_client_ids.size(); i++) { + client_t its_client_id = utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED + std::to_string(i), + VSOMEIP_CLIENT_UNSET); + EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); + if (its_client_id != VSOMEIP_CLIENT_UNSET) { + if (i > 0 && its_client_ids.back() != its_biggest_client) { + EXPECT_LT(its_client_ids.back(), its_client_id); + } + its_client_ids.push_back(its_client_id); + } else { + ADD_FAILURE() << "Received VSOMEIP_CLIENT_UNSET " + << static_cast(i); + } + } + + // check limit is reached + its_illegal_client_id = 0xFFFF; + its_illegal_client_id = utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); + EXPECT_EQ(VSOMEIP_CLIENT_UNSET, its_illegal_client_id); + + // release all + for (const client_t c : its_client_ids) { + utility::release_client_id(configuration_->get_network(), c); + } +} + +TEST_F(client_id_utility_test, request_released_client_id_after_maximum_client_id_is_assigned) { + std::vector its_client_ids; + std::uint16_t its_max_clients(0); + for (int var = 0; var < __builtin_popcount(static_cast(~diagnosis_mask_)); ++var) { + its_max_clients = static_cast(its_max_clients | (1 << var)); + } + const std::uint16_t max_possible_clients = its_max_clients; + // -1 for the routing manager, -2 as two predefined client IDs are present + // in the json file which aren't assigned via autoconfiguration + const std::uint16_t max_allowed_clients = static_cast(max_possible_clients - 2u); + + // acquire (almost) maximum amount of client IDs + for (std::uint16_t i = 0; i < max_allowed_clients - 1; i++) { + client_t its_client_id = utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); + EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); + if (its_client_id != VSOMEIP_CLIENT_UNSET) { + if (i > 0) { + EXPECT_LT(its_client_ids.back(), its_client_id); + } + its_client_ids.push_back(its_client_id); + } else { + ADD_FAILURE()<< "Received VSOMEIP_CLIENT_UNSET " + << static_cast(i); + } + } + + // release a client ID + utility::release_client_id(configuration_->get_network(), its_client_ids[10]); + + // requesting an ID should return the maximum possible ID + client_t its_max_client_id = utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); + EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_max_client_id); + its_client_ids.push_back(its_max_client_id); + + // requesting an ID should work as we have released one before + client_t its_client_id = utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); + EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); + its_client_ids.push_back(its_client_id); + + // requesting an ID should not work as all IDs are in use now + client_t its_illegal_client_id = utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); + EXPECT_EQ(VSOMEIP_CLIENT_UNSET, its_illegal_client_id); + + // release another ID + utility::release_client_id(configuration_->get_network(), its_client_ids[5]); + + its_client_id = utility::request_client_id(configuration_, + APPLICATION_NAME_NOT_PREDEFINED, VSOMEIP_CLIENT_UNSET); + EXPECT_NE(VSOMEIP_CLIENT_UNSET, its_client_id); + its_client_ids.push_back(its_client_id); + + // release all + for (const client_t c : its_client_ids) { + utility::release_client_id(configuration_->get_network(), c); + } + its_client_ids.clear(); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/client_id_tests/client_id_test_utility.json b/test/network_tests/client_id_tests/client_id_test_utility.json new file mode 100644 index 0000000..e07eb9a --- /dev/null +++ b/test/network_tests/client_id_tests/client_id_test_utility.json @@ -0,0 +1,35 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "diagnosis":"0x63", + "applications": + [ + { + "name":"client_id_test_utility_service_in", + "id":"0x6311" + }, + { + "name":"client_id_test_utility_service_in_two", + "id":"0x6312" + }, + { + "name":"client_id_test_utility_service_out_low", + "id":"0x5911" + }, + { + "name":"client_id_test_utility_service_out_high", + "id":"0x7411" + } + ], + "routing":"routingmanagerd" +} diff --git a/test/network_tests/client_id_tests/client_id_test_utility_discontinuous_masked_511.json b/test/network_tests/client_id_tests/client_id_test_utility_discontinuous_masked_511.json new file mode 100644 index 0000000..af3dfd6 --- /dev/null +++ b/test/network_tests/client_id_tests/client_id_test_utility_discontinuous_masked_511.json @@ -0,0 +1,36 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "diagnosis":"0x63", + "diagnosis_mask":"0xFB00", + "applications": + [ + { + "name":"client_id_test_utility_service_in", + "id":"0x6311" + }, + { + "name":"client_id_test_utility_service_in_two", + "id":"0x6312" + }, + { + "name":"client_id_test_utility_service_out_low", + "id":"0x5911" + }, + { + "name":"client_id_test_utility_service_out_high", + "id":"0x7411" + } + ], + "routing":"routingmanagerd" +} diff --git a/test/network_tests/client_id_tests/client_id_test_utility_masked_127.json b/test/network_tests/client_id_tests/client_id_test_utility_masked_127.json new file mode 100644 index 0000000..8aa5135 --- /dev/null +++ b/test/network_tests/client_id_tests/client_id_test_utility_masked_127.json @@ -0,0 +1,36 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "diagnosis":"0x63", + "diagnosis_mask":"0xFF80", + "applications": + [ + { + "name":"client_id_test_utility_service_in", + "id":"0x6311" + }, + { + "name":"client_id_test_utility_service_in_two", + "id":"0x6312" + }, + { + "name":"client_id_test_utility_service_out_low", + "id":"0x5911" + }, + { + "name":"client_id_test_utility_service_out_high", + "id":"0x7411" + } + ], + "routing":"routingmanagerd" +} diff --git a/test/network_tests/client_id_tests/client_id_test_utility_masked_4095.json b/test/network_tests/client_id_tests/client_id_test_utility_masked_4095.json new file mode 100644 index 0000000..8604435 --- /dev/null +++ b/test/network_tests/client_id_tests/client_id_test_utility_masked_4095.json @@ -0,0 +1,36 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "diagnosis":"0x60", + "diagnosis_mask":"0xF000", + "applications": + [ + { + "name":"client_id_test_utility_service_in", + "id":"0x6011" + }, + { + "name":"client_id_test_utility_service_in_two", + "id":"0x6012" + }, + { + "name":"client_id_test_utility_service_out_low", + "id":"0x5911" + }, + { + "name":"client_id_test_utility_service_out_high", + "id":"0x7411" + } + ], + "routing":"routingmanagerd" +} diff --git a/test/network_tests/client_id_tests/client_id_test_utility_masked_511.json b/test/network_tests/client_id_tests/client_id_test_utility_masked_511.json new file mode 100644 index 0000000..a57d382 --- /dev/null +++ b/test/network_tests/client_id_tests/client_id_test_utility_masked_511.json @@ -0,0 +1,36 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "diagnosis":"0x62", + "diagnosis_mask":"0xFE00", + "applications": + [ + { + "name":"client_id_test_utility_service_in", + "id":"0x6211" + }, + { + "name":"client_id_test_utility_service_in_two", + "id":"0x6212" + }, + { + "name":"client_id_test_utility_service_out_low", + "id":"0x5911" + }, + { + "name":"client_id_test_utility_service_out_high", + "id":"0x7411" + } + ], + "routing":"routingmanagerd" +} diff --git a/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_master.json.in b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_master.json.in new file mode 100644 index 0000000..a986dd9 --- /dev/null +++ b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_master.json.in @@ -0,0 +1,70 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"client_id_test_service_one", + "id":"0x1111" + }, + { + "name":"client_id_test_service_two", + "id":"0x2222" + }, + { + "name":"client_id_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1000", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2000", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3000", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + } + ], + "routing":"client_id_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} \ No newline at end of file diff --git a/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_slave.json.in b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_slave.json.in new file mode 100644 index 0000000..596f842 --- /dev/null +++ b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_diff_ports_slave.json.in @@ -0,0 +1,70 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"client_id_test_service_four", + "id":"0x4444" + }, + { + "name":"client_id_test_service_five", + "id":"0x5555" + }, + { + "name":"client_id_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4000", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5000", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6000", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + } + ], + "routing":"client_id_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} \ No newline at end of file diff --git a/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_master.json.in b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_master.json.in new file mode 100644 index 0000000..bb3507b --- /dev/null +++ b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_master.json.in @@ -0,0 +1,70 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"client_id_test_service_one", + "id":"0x1111" + }, + { + "name":"client_id_test_service_two", + "id":"0x2222" + }, + { + "name":"client_id_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1000", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2000", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3000", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing":"client_id_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} \ No newline at end of file diff --git a/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_slave.json.in b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_slave.json.in new file mode 100644 index 0000000..a7337e9 --- /dev/null +++ b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_partial_same_ports_slave.json.in @@ -0,0 +1,70 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"client_id_test_service_four", + "id":"0x4444" + }, + { + "name":"client_id_test_service_five", + "id":"0x5555" + }, + { + "name":"client_id_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4000", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5000", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6000", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing":"client_id_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} \ No newline at end of file diff --git a/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_master.json.in b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_master.json.in new file mode 100644 index 0000000..9f7062f --- /dev/null +++ b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_master.json.in @@ -0,0 +1,70 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"client_id_test_service_one", + "id":"0x1111" + }, + { + "name":"client_id_test_service_two", + "id":"0x2222" + }, + { + "name":"client_id_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1000", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2000", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3000", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing":"client_id_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} \ No newline at end of file diff --git a/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_slave.json.in b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_slave.json.in new file mode 100644 index 0000000..1aaf2cb --- /dev/null +++ b/test/network_tests/client_id_tests/conf/client_id_test_diff_client_ids_same_ports_slave.json.in @@ -0,0 +1,70 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"client_id_test_service_four", + "id":"0x4444" + }, + { + "name":"client_id_test_service_five", + "id":"0x5555" + }, + { + "name":"client_id_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4000", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5000", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6000", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing":"client_id_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} \ No newline at end of file diff --git a/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_master.json.in b/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_master.json.in new file mode 100644 index 0000000..a986dd9 --- /dev/null +++ b/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_master.json.in @@ -0,0 +1,70 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"client_id_test_service_one", + "id":"0x1111" + }, + { + "name":"client_id_test_service_two", + "id":"0x2222" + }, + { + "name":"client_id_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1000", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2000", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3000", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + } + ], + "routing":"client_id_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} \ No newline at end of file diff --git a/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_slave.json.in b/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_slave.json.in new file mode 100644 index 0000000..2acb37b --- /dev/null +++ b/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_diff_ports_slave.json.in @@ -0,0 +1,70 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"client_id_test_service_four", + "id":"0x1111" + }, + { + "name":"client_id_test_service_five", + "id":"0x2222" + }, + { + "name":"client_id_test_service_six", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x4000", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5000", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6000", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + } + ], + "routing":"client_id_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} \ No newline at end of file diff --git a/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_same_ports_master.json.in b/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_same_ports_master.json.in new file mode 100644 index 0000000..9f7062f --- /dev/null +++ b/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_same_ports_master.json.in @@ -0,0 +1,70 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"client_id_test_service_one", + "id":"0x1111" + }, + { + "name":"client_id_test_service_two", + "id":"0x2222" + }, + { + "name":"client_id_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1000", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2000", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3000", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing":"client_id_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} \ No newline at end of file diff --git a/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_same_ports_slave.json.in b/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_same_ports_slave.json.in new file mode 100644 index 0000000..ae534b1 --- /dev/null +++ b/test/network_tests/client_id_tests/conf/client_id_test_same_client_ids_same_ports_slave.json.in @@ -0,0 +1,70 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"client_id_test_service_four", + "id":"0x1111" + }, + { + "name":"client_id_test_service_five", + "id":"0x2222" + }, + { + "name":"client_id_test_service_six", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x4000", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5000", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6000", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing":"client_id_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} \ No newline at end of file diff --git a/test/network_tests/configuration_tests/configuration-test-deprecated.json b/test/network_tests/configuration_tests/configuration-test-deprecated.json new file mode 100644 index 0000000..5a8b0ee --- /dev/null +++ b/test/network_tests/configuration_tests/configuration-test-deprecated.json @@ -0,0 +1,496 @@ +{ + "unicast" : "10.0.2.15", + "diagnosis" : "85", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : { "enable" : "true", "path" : "/home/someip/another-file.log" }, + "dlt" : "false", + "version" : { + "enable" : "false", + "interval" : "15" + } + }, + "watchdog" : + { + "enable" : "true", + "timeout" : "1234", + "allowed_missing_pongs" : "7" + }, + "file-permissions" : + { + "permissions-shm" : "444", + "permissions-uds" : "222" + }, + "supports_selective_broadcasts" : + { + "address" : "160.160.160.160" + }, + "tracing" : + { + "enable" : "true", + "sd_enable" : "true", + "channels" : + [ + { + "name" : "testname", + "id" : "testid" + }, + { + "name" : "testname2", + "id" : "testid2" + }, + { + "name" : "testname3", + "id" : "testid3" + }, + { + "name" : "testname4", + "id" : "testid4" + } + ], + "filters" : + [ + { + "channel" : "testname", + "services" : ["0x1111",2222], + "type" : "positive" + }, + { + "channel" : "testname2", + "services" : ["0x3333",4444], + "type" : "negative" + } + ] + }, + "applications" : + [ + { + "name" : "my_application", + "id" : "0x7788", + "max_dispatchers" : "25", + "max_dispatch_time" : "1234", + "threads" : "12", + "request_debounce_time" : "5000", + "plugins" : + [ + { + "application_plugin" : "testlibraryname" + }, + { + "intentionally_wrong_plugin" : "wrong" + } + ] + }, + { + "name" : "other_application", + "id" : "0x9933", + "threads" : "0", + "threads" : "256", + "request_debounce_time" : "10001" + } + ], + "servicegroups" : + [ + { + "name" : "default", + "unicast" : "local", + "delays" : + { + "initial" : { "minimum" : "10", "maximum" : "100" }, + "repetition-base" : "200", + "repetition-max" : "7", + "cyclic-offer" : "2132", + "cyclic-request" : "2001", + "ttl" : "5" + }, + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x0022", + "reliable" : { "port" : "30506", "enable-magic-cookies" : "true" }, + "unreliable" : "31000", + "events" : + [ + { + "event" : "0x0778", + "is_field" : "false" + }, + { + "event" : "0x779", + "is_field" : "true" + }, + { + "event" : "0x77A", + "is_field" : "false" + } + ], + "eventgroups" : + [ + { + "eventgroup" : "0x4567", + "multicast" : "225.226.227.228", + "events" : [ "0x778", "0x779" ] + }, + { + "eventgroup" : "0x4569", + "multicast" : "225.227.227.228", + "events" : [ "0x779", "0x77A" ] + }, + { + "eventgroup" : "0x4569", + "multicast" : "225.222.227.228", + "events" : [ "0x778", "0x77A" ] + } + ] + }, + { + "service" : "0x1234", + "instance" : "0x0023", + "reliable" : "30503" + }, + { + "service" : "0x7809", + "instance" : "0x1", + "multicast" : + { + "address" : "224.212.244.225", + "port" : "1234" + }, + "eventgroups" : + [ + { + "eventgroup" : "0x1111", + "threshold" : "8", + "is_multicast" : "true", + "events" : [ "0x778", "0x77A" ] + } + ] + } + ] + }, + { + "name" : "extra", + "unicast" : "local", + "delays" : + { + "initial" : { "minimum" : "10", "maximum" : "100" }, + "repetition-base" : "200", + "repetition-max" : "7", + "cyclic-offer" : "2132", + "cyclic-request" : "2001", + "ttl" : "5" + }, + "services" : + [ + { + "service" : "0x2277", + "instance" : "0x0022", + "reliable" : { "port" : "30505" }, + "unreliable" : "31001" + }, + { + "service" : "0x2266", + "instance" : "0x0022", + "reliable" : "30505", + "unreliable" : "30507" + }, + { + "service" : "0x3333", + "instance" : "0x1" + }, + { + "service" : "0x3555", + "instance" : "0x1", + "protocol" : "other" + } + ] + }, + { + "name" : "remote", + "unicast" : "10.0.2.23", + "services" : + [ + { + "service" : "0x4466", + "instance" : "0x0321", + "reliable" : "30506", + "unreliable" : "30444" + } + ] + } + ], + "internal_services" : + [ + { + "first" : "0xF100", + "last" : "0xF109" + }, + { + "first" : { + "service" : "0xF300", + "instance" : "0x1" + }, + "last" : { + "service" : "0xF300", + "instance" : "0x10" + } + } + ], + "clients" : + [ + { + "reliable_remote_ports" : { "first" : "30500", "last" : "30599" }, + "unreliable_remote_ports" : { "first" : "30500", "last" : "30599" }, + "reliable_client_ports" : { "first" : "30491", "last" : "30499" }, + "unreliable_client_ports" : { "first" : "30491", "last" : "30499" } + }, + { + "reliable_remote_ports" : { "first" : "31500", "last" : "31599" }, + "unreliable_remote_ports" : { "first" : "31500", "last" : "31599" }, + "reliable_client_ports" : { "first" : "31491", "last" : "31499" }, + "unreliable_client_ports" : { "first" : "31491", "last" : "31499" } + }, + { + "reliable_remote_ports" : { "first" : "32500", "last" : "32599" }, + "unreliable_remote_ports" : { "first" : "32500", "last" : "32599" }, + "reliable_client_ports" : { "first" : "32491", "last" : "32499" }, + "unreliable_client_ports" : { "first" : "32491", "last" : "32499" } + }, + { + "service" : "0x8888", + "instance" : "0x1", + "unreliable" : [ "0x11", "0x10" ], + "reliable" : [ "0x11", "0x10" ] + }, + { + "service" : "8888", + "instance" : "1", + "unreliable" : [ 40000, 40001 ], + "reliable" : [ 40000, 40001 ] + } + ], + "tcp-restart-aborts-max" : "15", + "tcp-connect-time-max" : "10000", + "max-payload-size-local" : "15000", + "max-payload-size-reliable" : "17000", + "buffer-shrink-threshold" : "11", + "payload-sizes": + [ + { + "unicast":"10.10.10.10", + "ports": + [ + { + "port":"7777", + "max-payload-size":"14999" + } + ] + }, + { + "unicast":"10.10.10.11", + "ports": + [ + { + "port":"7778", + "max-payload-size":"15001" + } + ] + } + ], + "security" : + { + "check_credentials" : "true", + "policies" : + [ + { + "credentials" : { "uid" : "1000", "gid" : "1000" }, + "allow" : + { + "offers": + [ + { + "service" : "0x1234", + "instance" : "0x5678" + }, + { + "service" : "0x1235", + "instance" : "0x5678" + }, + { + "service" : "0x1236", + "instances" : [{ "first" : "0x5675", "last" : "0x5677"}, "0x5678"] + } + ] + } + }, + { + "credentials" : { "uid" : "2000", "gid" : "2000" }, + "allow" : + { + "requests": + [ + { + "service" : "0x1234", + "instances" : [ + { + "ids" : ["0x5678", { "first" : "0x5679", "last" : "0x5699"}], + "methods" : [ "0x0001", { "first" : "0x8001", "last" : "0x8006" }] + } + ] + }, + { + "service" : "0x1237", + "instances" : [ + { + "ids" : ["0x5678"], + "methods" : "any" + } + ] + }, + { + "service" : "0x1238", + "instances" : [ + { + "ids" : "any", + "methods" : ["0x0001"] + } + ] + } + ] + } + }, + { + "credentials" : { "uid" : "4000", "gid" : "4000" }, + "deny" : + { + "requests": + [ + { + "service" : "0x1234", + "instances" : [ + { + "ids" : ["0x5678", { "first" : "0x5679", "last" : "0x5699"}], + "methods" : [ "0x0002", { "first" : "0x9001", "last" : "0x9006" }] + } + ] + } + ], + "offers": + [ + { + "service" : "0x1234", + "instance" : "0x5678" + }, + { + "service" : "0x1235", + "instance" : "0x5678" + }, + { + "service" : "0x1236", + "instances" : [{ "first" : "0x5675", "last" : "0x5677"}, "0x5678"] + } + ] + } + }, + { + "credentials" : { "uid" : "5000", "gid" : "5000" }, + "deny" : + { + } + }, + { + "credentials" : { "uid" : "6000", "gid" : "6000" }, + "allow" : + { + } + }, + { + "credentials" : { "uid" : "7000", "gid" : "7000" }, + "deny" : + { + "requests": + [ + { + "service" : "0x1234", + "instances" : [ + { + "ids" : ["0x5678"], + "methods" : "any" + } + ] + } + ] + } + }, + { + "credentials" : { "uid" : "8000", "gid" : "8000" }, + "allow" : + { + "requests": + [ + { + "service" : "0x1234", + "instances" : [ + { + "ids" : ["0x5678"], + "methods" : "any" + } + ] + } + ] + } + }, + { + "credentials" : { + "allow": [ + { + "uid": [ + "9000" + ], + "gid": [ + "9000" + ] + } + ] + }, + "deny" : + { + } + } + ] + }, + "security-update-whitelist" : + { + "uids" : + [ + {"first" : "1000", "last" : "1008"}, + {"first" : "1100", "last" : "1200"}, + "2000", + "3000" + ], + "services" : + [ + {"first" : "0x1234", "last" : "0x1238"}, + {"first" : "0x2000", "last" : "0x2500"}, + "0x7800" + ], + "check-whitelist" : "true" + }, + "routing" : "my_application", + "routing-credentials" : + { + "uid" : "0x123", + "gid" : "0x456" + }, + "service-discovery" : + { + "enable" : "true", + "protocol" : "udp", + "multicast" : "224.212.244.223", + "port" : "30666", + "offer_debounce_time" : "1000" + } +} diff --git a/test/network_tests/configuration_tests/configuration-test.cpp b/test/network_tests/configuration_tests/configuration-test.cpp new file mode 100644 index 0000000..800852e --- /dev/null +++ b/test/network_tests/configuration_tests/configuration-test.cpp @@ -0,0 +1,832 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include + +#include + +#include "../../common/utility.hpp" + +#include +#include +#include +#include "../implementation/configuration/include/configuration.hpp" + +#include "../../implementation/plugin/include/plugin_manager_impl.hpp" +#include "../../implementation/configuration/include/configuration_impl.hpp" +#include "../../implementation/configuration/include/configuration_plugin.hpp" +#include "../../implementation/protocol/include/protocol.hpp" +#include "../../implementation/security/include/policy_manager_impl.hpp" + +namespace vsomeip = vsomeip_v3; + +#define CONFIGURATION_FILE "configuration-test.json" +#define DEPRECATED_CONFIGURATION_FILE "configuration-test-deprecated.json" + +#define EXPECTED_UNICAST_ADDRESS "10.0.2.15" + +#define EXPECTED_HAS_CONSOLE true +#define EXPECTED_HAS_FILE true +#define EXPECTED_HAS_DLT false +#define EXPECTED_LOGLEVEL "debug" +#define EXPECTED_LOGFILE "/home/someip/another-file.log" + +#define EXPECTED_ROUTING_MANAGER_HOST "my_application" + +// Logging +#define EXPECTED_VERSION_LOGGING_ENABLED false +#define EXPECTED_VERSION_LOGGING_INTERVAL 15 + +// Application +#define EXPECTED_APPLICATION_MAX_DISPATCHERS 25 +#define EXPECTED_APPLICATION_MAX_DISPATCH_TIME 1234 +#define EXPECTED_APPLICATION_THREADS 12 +#define EXPECTED_APPLICATION_REQUEST_DEBOUNCE_TIME 5000 + +// Services +#define EXPECTED_UNICAST_ADDRESS_1234_0022 EXPECTED_UNICAST_ADDRESS +#define EXPECTED_RELIABLE_PORT_1234_0022 30506 +#define EXPECTED_UNRELIABLE_PORT_1234_0022 31000 + +#define EXPECTED_UNICAST_ADDRESS_1234_0023 EXPECTED_UNICAST_ADDRESS +#define EXPECTED_RELIABLE_PORT_1234_0023 30503 +#define EXPECTED_UNRELIABLE_PORT_1234_0023 vsomeip::ILLEGAL_PORT + +#define EXPECTED_UNICAST_ADDRESS_2277_0022 EXPECTED_UNICAST_ADDRESS +#define EXPECTED_RELIABLE_PORT_2277_0022 30505 +#define EXPECTED_UNRELIABLE_PORT_2277_0022 31001 + +#define EXPECTED_UNICAST_ADDRESS_2266_0022 EXPECTED_UNICAST_ADDRESS +#define EXPECTED_RELIABLE_PORT_2266_0022 30505 +#define EXPECTED_UNRELIABLE_PORT_2266_0022 30507 + +#define EXPECTED_UNICAST_ADDRESS_4466_0321 "10.0.2.23" +#define EXPECTED_RELIABLE_PORT_4466_0321 30506 +#define EXPECTED_UNRELIABLE_PORT_4466_0321 30444 + +// Service Discovery +#define EXPECTED_SD_ENABLED true +#define EXPECTED_SD_PROTOCOL "udp" +#define EXPECTED_SD_MULTICAST "224.212.244.223" +#define EXPECTED_SD_PORT 30666 + +#define EXPECTED_INITIAL_DELAY_MIN 1234 +#define EXPECTED_INITIAL_DELAY_MAX 2345 +#define EXPECTED_REPETITIONS_BASE_DELAY 4242 +#define EXPECTED_REPETITIONS_MAX 4 +#define EXPECTED_TTL 13 +#define EXPECTED_CYCLIC_OFFER_DELAY 2132 +#define EXPECTED_REQUEST_RESPONSE_DELAY 1111 + +#define EXPECTED_DEPRECATED_INITIAL_DELAY_MIN 10 +#define EXPECTED_DEPRECATED_INITIAL_DELAY_MAX 100 +#define EXPECTED_DEPRECATED_REPETITIONS_BASE_DELAY 200 +#define EXPECTED_DEPRECATED_REPETITIONS_MAX 7 +#define EXPECTED_DEPRECATED_TTL 5 +#define EXPECTED_DEPRECATED_REQUEST_RESPONSE_DELAY 2001 + +template +::testing::AssertionResult check(const T &_is, const T &_expected, const std::string &_test) { + if (_is == _expected) { + return ::testing::AssertionSuccess() << "Test \"" << _test << "\" succeeded."; + } else { + return ::testing::AssertionFailure() << "Test \"" << _test << "\" failed! (" + << _is << " != " << _expected << ")"; + } +} + +std::string loglevel_to_string(vsomeip::logger::level_e &_level) { + switch (_level) { + case vsomeip::logger::level_e::LL_FATAL: + return "fatal"; + case vsomeip::logger::level_e::LL_ERROR: + return "error"; + case vsomeip::logger::level_e::LL_WARNING: + return "warning"; + case vsomeip::logger::level_e::LL_INFO: + return "info"; + case vsomeip::logger::level_e::LL_DEBUG: + return "debug"; + case vsomeip::logger::level_e::LL_VERBOSE: + return "verbose"; + default: + return "unknown"; + } +} + +void check_file(const std::string &_config_file, + const std::string &_expected_unicast_address, + bool _expected_has_console, + bool _expected_has_file, + bool _expected_has_dlt, + bool _expected_version_logging_enabled, + uint32_t _expected_version_logging_interval, + uint32_t _expected_application_max_dispatcher, + uint32_t _expected_application_max_dispatch_time, + uint32_t _expected_application_threads, + uint32_t _expected_application_request_debounce_time, + const std::string &_expected_logfile, + const std::string &_expected_loglevel, + const std::string &_expected_unicast_address_1234_0022, + uint16_t _expected_reliable_port_1234_0022, + uint16_t _expected_unreliable_port_1234_0022, + const std::string &_expected_unicast_address_1234_0023, + uint16_t _expected_reliable_port_1234_0023, + uint16_t _expected_unreliable_port_1234_0023, + const std::string &_expected_unicast_address_2277_0022, + uint16_t _expected_reliable_port_2277_0022, + uint16_t _expected_unreliable_port_2277_0022, + const std::string &_expected_unicast_address_2266_0022, + uint16_t _expected_reliable_port_2266_0022, + uint16_t _expected_unreliable_port_2266_0022, + const std::string &_expected_unicast_address_4466_0321, + uint16_t _expected_reliable_port_4466_0321, + uint16_t _expected_unreliable_port_4466_0321, + bool _expected_enabled, + const std::string &_expected_protocol, + const std::string &_expected_multicast, + uint16_t _expected_port, + uint32_t _expected_initial_delay_min, + uint32_t _expected_initial_delay_max, + int32_t _expected_repetitions_base_delay, + uint8_t _expected_repetitions_max, + vsomeip::ttl_t _expected_ttl, + vsomeip::ttl_t _expected_cyclic_offer_delay, + vsomeip::ttl_t _expected_request_response_delay) { + + + // 0. Set environment variable to config file and load it +#if defined(__linux__) || defined(ANDROID) + setenv("VSOMEIP_CONFIGURATION", _config_file.c_str(), 1); +#else + _putenv_s("VSOMEIP_CONFIGURATION", _config_file.c_str() +#endif + + // 1. Create configuration object + std::shared_ptr its_configuration; + auto its_plugin = vsomeip::plugin_manager_impl::get()->get_plugin( + vsomeip::plugin_type_e::CONFIGURATION_PLUGIN, VSOMEIP_CFG_LIBRARY); + if (its_plugin) { + auto its_configuration_plugin + = std::dynamic_pointer_cast(its_plugin); + if (its_configuration_plugin) + its_configuration = its_configuration_plugin->get_configuration(EXPECTED_ROUTING_MANAGER_HOST, ""); + } + + // 2. Did we get a configuration object? + if (0 == its_configuration) { + ADD_FAILURE() << "No configuration object. " + "Either memory overflow or loading error detected!"; + return; + } + + vsomeip::cfg::configuration_impl its_copied_config( + static_cast(*its_configuration)); + vsomeip::cfg::configuration_impl* its_new_config = + new vsomeip::cfg::configuration_impl(its_copied_config); + delete its_new_config; + + its_configuration->set_configuration_path("/my/test/path"); + + // 3. Check host address + boost::asio::ip::address its_host_unicast_address + = its_configuration->get_unicast_address(); + EXPECT_TRUE(check(its_host_unicast_address.to_string(), + _expected_unicast_address, "UNICAST ADDRESS")); + EXPECT_TRUE(its_configuration->is_v4()); + EXPECT_FALSE(its_configuration->is_v6()); + + // check diagnosis prefix + EXPECT_NE(0x54, its_configuration->get_diagnosis_address()); + EXPECT_EQ(0x55, its_configuration->get_diagnosis_address()); + EXPECT_NE(0x56, its_configuration->get_diagnosis_address()); + + // 4. Check logging + bool has_console = its_configuration->has_console_log(); + bool has_file = its_configuration->has_file_log(); + bool has_dlt = its_configuration->has_dlt_log(); + std::string logfile = its_configuration->get_logfile(); + vsomeip::logger::level_e loglevel + = its_configuration->get_loglevel(); + bool has_version_logging = its_configuration->log_version(); + std::uint32_t version_logging_interval = its_configuration->get_log_version_interval(); + + EXPECT_TRUE(check(has_console, _expected_has_console, "HAS CONSOLE")); + EXPECT_TRUE(check(has_file, _expected_has_file, "HAS FILE")); + EXPECT_TRUE(check(has_dlt, _expected_has_dlt, "HAS DLT")); + EXPECT_TRUE(check(logfile, _expected_logfile, "LOGFILE")); + EXPECT_TRUE(check(loglevel_to_string(loglevel), + _expected_loglevel, "LOGLEVEL")); + EXPECT_TRUE(check(has_version_logging, _expected_version_logging_enabled, + "VERSION LOGGING")); + EXPECT_TRUE(check(version_logging_interval, + _expected_version_logging_interval, + "VERSION LOGGING INTERVAL")); + + // watchdog + EXPECT_TRUE(its_configuration->is_watchdog_enabled()); + EXPECT_EQ(1234u, its_configuration->get_watchdog_timeout()); + EXPECT_EQ(7u, its_configuration->get_allowed_missing_pongs()); + + // file permissions + EXPECT_EQ(0444u, its_configuration->get_permissions_shm()); + EXPECT_EQ(0222u, its_configuration->get_permissions_uds()); + + // selective broadcasts + EXPECT_TRUE(its_configuration->supports_selective_broadcasts( + boost::asio::ip::address::from_string("160.160.160.160"))); + + // tracing + std::shared_ptr its_trace = its_configuration->get_trace(); + EXPECT_TRUE(its_trace->is_enabled_); + EXPECT_TRUE(its_trace->is_sd_enabled_); + EXPECT_EQ(4u, its_trace->channels_.size()); + EXPECT_TRUE(its_trace->filters_.size() == 2u || its_trace->filters_.size() == 4u); + for (const auto &c : its_trace->channels_) { + EXPECT_TRUE(c->name_ == std::string("testname") || c->name_ == std::string("testname2") || + c->name_ == std::string("testname3") || c->name_ == std::string("testname4")); + if (c->name_ == std::string("testname")) { + EXPECT_EQ(std::string("testid"), c->id_); + } else if (c->name_ == std::string("testname2")) { + EXPECT_EQ(std::string("testid2"), c->id_); + } else if (c->name_ == std::string("testname3")) { + EXPECT_EQ(std::string("testid3"), c->id_); + } else if (c->name_ == std::string("testname4")) { + EXPECT_EQ(std::string("testid4"), c->id_); + } + } + for (const auto &f : its_trace->filters_) { + auto its_channel_name = f->channels_.front(); + auto its_matches = f->matches_; + EXPECT_TRUE(its_channel_name == std::string("testname") || its_channel_name == std::string("testname2") || + its_channel_name == std::string("testname3") || its_channel_name == std::string("testname4")); + if (its_channel_name == std::string("testname")) { + EXPECT_EQ(2u, its_matches.size()); + + for (const vsomeip::trace::match_t &m : its_matches) { + EXPECT_TRUE(std::get<0>(m) == vsomeip::service_t(0x1111) || + std::get<0>(m) == vsomeip::service_t(2222)); + EXPECT_TRUE(std::get<1>(m) == vsomeip::instance_t(0xffff)); + EXPECT_TRUE(std::get<2>(m) == vsomeip::method_t(0xffff)); + EXPECT_EQ(f->ftype_, vsomeip_v3::trace::filter_type_e::POSITIVE); + EXPECT_FALSE(f->is_range_); + } + } else if (its_channel_name == std::string("testname2")) { + EXPECT_EQ(2u, its_matches.size()); + + for (const vsomeip::trace::match_t &m : its_matches) { + EXPECT_TRUE(std::get<0>(m) == vsomeip::service_t(0x3333) || + std::get<0>(m) == vsomeip::service_t(4444)); + EXPECT_TRUE(std::get<1>(m) == vsomeip::instance_t(0xffff)); + EXPECT_TRUE(std::get<2>(m) == vsomeip::method_t(0xffff)); + EXPECT_NE(f->ftype_, vsomeip_v3::trace::filter_type_e::POSITIVE); + EXPECT_FALSE(f->is_range_); + } + } else if (its_channel_name == std::string("testname3")) { + EXPECT_EQ(2u, its_matches.size()); + + for (const vsomeip::trace::match_t &m : its_matches) { + EXPECT_TRUE(std::get<0>(m) == vsomeip::service_t(0x1111) || + std::get<0>(m) == vsomeip::service_t(0x3333)); + EXPECT_TRUE(std::get<1>(m) == vsomeip::instance_t(0xffff)); + EXPECT_TRUE(std::get<2>(m) == vsomeip::method_t(0xffff) || + std::get<2>(m) == vsomeip::method_t(0x8888)); + EXPECT_NE(f->ftype_, vsomeip_v3::trace::filter_type_e::POSITIVE); + EXPECT_FALSE(f->is_range_); + } + } else if (its_channel_name == std::string("testname4")) { + EXPECT_EQ(2u, its_matches.size()); + + for (const vsomeip::trace::match_t &m : its_matches) { + EXPECT_TRUE(std::get<0>(m) == vsomeip::service_t(0x1111) || + std::get<0>(m) == vsomeip::service_t(0x3333)); + EXPECT_TRUE(std::get<1>(m) == vsomeip::instance_t(0x0001)); + EXPECT_TRUE(std::get<2>(m) == vsomeip::method_t(0xffff) || + std::get<2>(m) == vsomeip::method_t(0x8888)); + EXPECT_NE(f->ftype_, vsomeip_v3::trace::filter_type_e::POSITIVE); + EXPECT_TRUE(f->is_range_); + } + } + } + + // Applications + std::size_t max_dispatchers = its_configuration->get_max_dispatchers( + EXPECTED_ROUTING_MANAGER_HOST); + std::size_t max_dispatch_time = its_configuration->get_max_dispatch_time( + EXPECTED_ROUTING_MANAGER_HOST); + std::size_t io_threads = its_configuration->get_io_thread_count( + EXPECTED_ROUTING_MANAGER_HOST); + std::size_t request_time = its_configuration->get_request_debouncing( + EXPECTED_ROUTING_MANAGER_HOST); + + EXPECT_TRUE(check(max_dispatchers, + _expected_application_max_dispatcher, "MAX DISPATCHERS")); + EXPECT_TRUE(check(max_dispatch_time, + _expected_application_max_dispatch_time, "MAX DISPATCH TIME")); + EXPECT_TRUE(check(io_threads, _expected_application_threads, + "IO THREADS")); + EXPECT_TRUE(check(request_time, + _expected_application_request_debounce_time, "REQUEST DEBOUNCE TIME")); + + EXPECT_EQ(0x9933, its_configuration->get_id("other_application")); + + std::map> its_plugins = + its_configuration->get_plugins(EXPECTED_ROUTING_MANAGER_HOST); + EXPECT_EQ(1u, its_plugins.size()); + for (const auto& plugin : its_plugins) { + EXPECT_EQ(vsomeip::plugin_type_e::APPLICATION_PLUGIN, plugin.first); + for (const auto& its_library : plugin.second) + EXPECT_EQ(std::string("libtestlibraryname.so." + std::to_string(VSOMEIP_APPLICATION_PLUGIN_VERSION)), its_library); + } + EXPECT_EQ(vsomeip::plugin_type_e::CONFIGURATION_PLUGIN, its_plugin->get_plugin_type()); + EXPECT_EQ("vsomeip-configuration-plugin", its_plugin->get_plugin_name()); + EXPECT_EQ(1u, its_plugin->get_plugin_version()); + + + // 5. Services + std::string its_unicast_address + = its_configuration->get_unicast_address(0x1234, 0x0022); + uint16_t its_reliable_port + = its_configuration->get_reliable_port(0x1234, 0x0022); + uint16_t its_unreliable_port + = its_configuration->get_unreliable_port(0x1234, 0x0022); + + EXPECT_TRUE(check(its_unicast_address, + _expected_unicast_address_1234_0022, + "UNICAST_ADDRESS_1234_0022")); + EXPECT_TRUE(check(its_reliable_port, + _expected_reliable_port_1234_0022, + "RELIABLE_PORT_1234_0022")); + EXPECT_TRUE(check(its_unreliable_port, + _expected_unreliable_port_1234_0022, + "UNRELIABLE_PORT_1234_0022")); + + its_unicast_address + = its_configuration->get_unicast_address(0x1234, 0x0023); + its_reliable_port + = its_configuration->get_reliable_port(0x1234, 0x0023); + its_unreliable_port + = its_configuration->get_unreliable_port(0x1234, 0x0023); + + EXPECT_TRUE(check(its_unicast_address, + _expected_unicast_address_1234_0023, + "UNICAST_ADDRESS_1234_0023")); + EXPECT_TRUE(check(its_reliable_port, + _expected_reliable_port_1234_0023, + "RELIABLE_PORT_1234_0023")); + EXPECT_TRUE(check(its_unreliable_port, + _expected_unreliable_port_1234_0023, + "UNRELIABLE_PORT_1234_0023")); + + its_unicast_address + = its_configuration->get_unicast_address(0x2277, 0x0022); + its_reliable_port + = its_configuration->get_reliable_port(0x2277, 0x0022); + its_unreliable_port + = its_configuration->get_unreliable_port(0x2277, 0x0022); + + EXPECT_TRUE(check(its_unicast_address, + _expected_unicast_address_2277_0022, + "UNICAST_ADDRESS_2277_0022")); + EXPECT_TRUE(check(its_reliable_port, + _expected_reliable_port_2277_0022, + "RELIABLE_PORT_2277_0022")); + EXPECT_TRUE(check(its_unreliable_port, + _expected_unreliable_port_2277_0022, + "UNRELIABLE_PORT_2277_0022")); + + its_unicast_address + = its_configuration->get_unicast_address(0x2266, 0x0022); + its_reliable_port + = its_configuration->get_reliable_port(0x2266, 0x0022); + its_unreliable_port + = its_configuration->get_unreliable_port(0x2266, 0x0022); + + EXPECT_TRUE(check(its_unicast_address, + _expected_unicast_address_2266_0022, + "UNICAST_ADDRESS_2266_0022")); + EXPECT_TRUE(check(its_reliable_port, + _expected_reliable_port_2266_0022, + "RELIABLE_PORT_2266_0022")); + EXPECT_TRUE(check(its_unreliable_port, + _expected_unreliable_port_2266_0022, + "UNRELIABLE_PORT_2266_0022")); + + its_unicast_address + = its_configuration->get_unicast_address(0x4466, 0x0321); + its_reliable_port + = its_configuration->get_reliable_port(0x4466, 0x0321); + its_unreliable_port + = its_configuration->get_unreliable_port(0x4466, 0x0321); + + EXPECT_TRUE(check(its_unicast_address, + _expected_unicast_address_4466_0321, + "UNICAST_ADDRESS_4466_0321")); + EXPECT_TRUE(check(its_reliable_port, + _expected_reliable_port_4466_0321, + "RELIABLE_PORT_4466_0321")); + EXPECT_TRUE(check(its_unreliable_port, + _expected_unreliable_port_4466_0321, + "UNRELIABLE_PORT_4466_0321")); + + std::string its_multicast_address; + std::uint16_t its_multicast_port; + its_configuration->get_multicast(0x7809, 0x1, 0x1111, + its_multicast_address, its_multicast_port); + EXPECT_EQ(1234u, its_multicast_port); + EXPECT_EQ(std::string("224.212.244.225"), its_multicast_address); + EXPECT_EQ(8u, its_configuration->get_threshold(0x7809, 0x1, 0x1111)); + + EXPECT_TRUE(its_configuration->is_offered_remote(0x1234,0x0022)); + EXPECT_FALSE(its_configuration->is_offered_remote(0x3333,0x1)); + + EXPECT_TRUE(its_configuration->has_enabled_magic_cookies("10.0.2.15", 30506)); + EXPECT_FALSE(its_configuration->has_enabled_magic_cookies("10.0.2.15", 30503)); + + std::set> its_remote_services = + its_configuration->get_remote_services(); + EXPECT_EQ(1u, its_remote_services.size()); + for (const auto &p : its_remote_services) { + EXPECT_EQ(0x4466, p.first); + EXPECT_EQ(0x321, p.second); + } + + EXPECT_TRUE(its_configuration->is_someip(0x3333,0x1)); + EXPECT_FALSE(its_configuration->is_someip(0x3555,0x1)); + + // Internal services + EXPECT_TRUE(its_configuration->is_local_service(0x1234, 0x0022)); + EXPECT_TRUE(its_configuration->is_local_service(0x3333,0x1)); + // defined range, service level only + EXPECT_FALSE(its_configuration->is_local_service(0xF0FF,0x1)); + EXPECT_TRUE(its_configuration->is_local_service(0xF100,0x1)); + EXPECT_TRUE(its_configuration->is_local_service(0xF101,0x23)); + EXPECT_TRUE(its_configuration->is_local_service(0xF109,0xFFFF)); + EXPECT_FALSE(its_configuration->is_local_service(0xF10a,0x1)); + // defined range, service and instance level + EXPECT_FALSE(its_configuration->is_local_service(0xF2FF,0xFFFF)); + EXPECT_TRUE(its_configuration->is_local_service(0xF300,0x1)); + EXPECT_TRUE(its_configuration->is_local_service(0xF300,0x5)); + EXPECT_TRUE(its_configuration->is_local_service(0xF300,0x10)); + EXPECT_FALSE(its_configuration->is_local_service(0xF300,0x11)); + EXPECT_FALSE(its_configuration->is_local_service(0xF301,0x11)); + + // clients + std::map> used_ports; + used_ports[true].insert(0x11); + used_ports[false].insert(0x10); + std::uint16_t port_to_use(0x0); + EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x1, vsomeip::ILLEGAL_PORT, true, used_ports, port_to_use)); + EXPECT_EQ(0x10, port_to_use); + EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x1, vsomeip::ILLEGAL_PORT, false, used_ports, port_to_use)); + EXPECT_EQ(0x11, port_to_use); + + used_ports[true].insert(0x10); + used_ports[false].insert(0x11); + EXPECT_FALSE(its_configuration->get_client_port(0x8888, 0x1, vsomeip::ILLEGAL_PORT, true, used_ports, port_to_use)); + EXPECT_EQ(vsomeip::ILLEGAL_PORT, port_to_use); + EXPECT_FALSE(its_configuration->get_client_port(0x8888, 0x1, vsomeip::ILLEGAL_PORT, false, used_ports, port_to_use)); + EXPECT_EQ(vsomeip::ILLEGAL_PORT, port_to_use); + + + //check for correct client port assignment if service / instance was not configured but a remote port range + used_ports.clear(); + EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x12, 0x7725, true, used_ports, port_to_use)); + EXPECT_EQ(0x771B, port_to_use); + used_ports[true].insert(0x771B); + EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x12, 0x7725, true, used_ports, port_to_use)); + EXPECT_EQ(0x771C, port_to_use); + used_ports[true].insert(0x771C); + EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x12, 0x7B0D, true, used_ports, port_to_use)); + EXPECT_EQ(0x7B03, port_to_use); + used_ports[true].insert(0x7B03); + EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x12, 0x7B0D, true, used_ports, port_to_use)); + EXPECT_EQ(0x7B04, port_to_use); + used_ports[true].insert(0x7B04); + EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x12, 0x7EF4, true, used_ports, port_to_use)); + EXPECT_EQ(0x7EEB, port_to_use); + used_ports[true].insert(0x7EEB); + EXPECT_TRUE(its_configuration->get_client_port(0x8888, 0x12, 0x7EF4, true, used_ports, port_to_use)); + EXPECT_EQ(0x7EEC, port_to_use); + used_ports[true].insert(0x7EEC); + used_ports.clear(); + + + // payload sizes + // use 17000 instead of 1500 as configured max-local-payload size will be + // increased to bigger max-reliable-payload-size + std::uint32_t max_local_message_size( + 17000u + 16u + vsomeip::protocol::SEND_COMMAND_HEADER_SIZE); + EXPECT_EQ(max_local_message_size, its_configuration->get_max_message_size_local()); + EXPECT_EQ(11u, its_configuration->get_buffer_shrink_threshold()); + EXPECT_EQ(14999u + 16u, its_configuration->get_max_message_size_reliable("10.10.10.10", 7777)); + EXPECT_EQ(17000u + 16, its_configuration->get_max_message_size_reliable("11.11.11.11", 4711)); + EXPECT_EQ(15001u + 16, its_configuration->get_max_message_size_reliable("10.10.10.11", 7778)); + + // security +#ifndef VSOMEIP_DISABLE_SECURITY + vsomeip_sec_client_t its_x123_x456 = utility::create_uds_client(0x123, 0x456); + EXPECT_TRUE(its_configuration->check_routing_credentials(0x7788, &its_x123_x456)); + + // GID does not match + vsomeip_sec_client_t its_x123_x222 = utility::create_uds_client(0x123, 0x222); + EXPECT_FALSE(its_configuration->check_routing_credentials(0x7788, &its_x123_x222)); + + // UID does not match + vsomeip_sec_client_t its_x333_x456 = utility::create_uds_client(0x333, 0x456); + EXPECT_FALSE(its_configuration->check_routing_credentials(0x7788, &its_x333_x456)); + + // client is not the routing manager + vsomeip_sec_client_t its_x888_x999 = utility::create_uds_client(0x888, 0x999); + EXPECT_TRUE(its_configuration->check_routing_credentials(0x7777, &its_x888_x999)); + + EXPECT_TRUE(its_configuration->is_security_enabled()); + vsomeip_sec_client_t its_1000_1000 = utility::create_uds_client(1000, 1000); + vsomeip_sec_client_t its_1001_1001 = utility::create_uds_client(1001, 1001); + vsomeip_sec_client_t its_2000_2000 = utility::create_uds_client(2000, 2000); + vsomeip_sec_client_t its_2001_2001 = utility::create_uds_client(2001, 2001); + vsomeip_sec_client_t its_4000_4000 = utility::create_uds_client(4000, 4000); + vsomeip_sec_client_t its_4001_4001 = utility::create_uds_client(4001, 4001); + vsomeip_sec_client_t its_5000_5000 = utility::create_uds_client(5000, 5000); + vsomeip_sec_client_t its_6000_6000 = utility::create_uds_client(6000, 6000); + vsomeip_sec_client_t its_7000_7000 = utility::create_uds_client(7000, 7000); + vsomeip_sec_client_t its_8000_8000 = utility::create_uds_client(8000, 8000); + vsomeip_sec_client_t its_9000_9000 = utility::create_uds_client(9000, 9000); + + auto its_security = vsomeip::policy_manager_impl::get(); + EXPECT_TRUE(its_security->is_offer_allowed(&its_1000_1000, 0x1234, 0x5678)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_1000_1000, 0x1235, 0x5678)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_1000_1000, 0x1236, 0x5678)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_1000_1000, 0x1236, 0x5676)); + + EXPECT_FALSE(its_security->is_offer_allowed(&its_1000_1000, 0x1236, 0x5679)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_1000_1000, 0x1234, 0x5679)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_1000_1000, 0x1233, 0x5679)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_1001_1001, 0x1233, 0x5679)); + // explicitly denied offers + EXPECT_FALSE(its_security->is_offer_allowed(&its_4000_4000, 0x1234, 0x5678)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_4000_4000, 0x1235, 0x5678)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_4000_4000, 0x1234, 0x5679)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_4000_4000, 0x1300, 0x1)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_4000_4000, 0x1300, 0x2)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_4000_4000, 0x1236, 0x5678)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_4000_4000, 0x1236, 0x5675)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_4000_4000, 0x1236, 0x5676)); + EXPECT_FALSE(its_security->is_offer_allowed(&its_4000_4000, 0x1236, 0x5677)); + EXPECT_TRUE(its_security->is_offer_allowed(&its_4000_4000, 0x1236, 0x5679)); + + // explicitly allowed requests of methods / events + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5678, 0x0001)); + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5678, 0x8002)); + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5688, 0x8002)); + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5699, 0x8006)); + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5699, 0x8001)); + + EXPECT_FALSE(its_security->is_client_allowed(&its_2001_2001, 0x1234, 0x5678, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2001_2001, 0x1234, 0x5678, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5677, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5700, 0x0001)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5699, 0x8007)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1234, 0x5700, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1230, 0x5678, 0x0001)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1230, 0x5678, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4000_4000, 0x1234, 0x5678, 0x0002)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4000_4000, 0x1234, 0x5678, 0xFFFF)); + EXPECT_TRUE(its_security->is_client_allowed(&its_4000_4000, 0x1234, 0x5679, 0x0003)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4000_4000, 0x1234, 0x5679, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4000_4000, 0x1234, 0x5699, 0x9001)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4000_4000, 0x1234, 0x5699, 0x9006)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4001_4001, 0x1234, 0x5678, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_4001_4001, 0x1234, 0x5678, 0xFFFF)); + + // check that any method ID is allowed + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1237, 0x5678, 0x0001)); + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1237, 0x5678, 0xFFFF)); + + // check that any instance ID is allowed but only one method ID + EXPECT_TRUE(its_security->is_client_allowed(&its_2000_2000, 0x1238, 0x0004, 0x0001)); + EXPECT_FALSE(its_security->is_client_allowed(&its_2000_2000, 0x1238, 0x0004, 0x0002)); + + // DENY NOTHING policy + // check that ANY_METHOD is allowed in a "deny nothing" policy + EXPECT_TRUE(its_security->is_client_allowed(&its_5000_5000, 0x1234, 0x5678, 0xFFFF)); + // check that specific method ID is allowed in a "deny nothing" policy + EXPECT_TRUE(its_security->is_client_allowed(&its_5000_5000, 0x1234, 0x5678, 0x0001)); + + // ALLOW NOTHING policy + // check that ANY_METHOD is denied in a "allow nothing" policy + EXPECT_FALSE(its_security->is_client_allowed(&its_6000_6000, 0x1234, 0x5678, 0xFFFF)); + // check that specific method ID is denied in a "allow nothing" policy + EXPECT_FALSE(its_security->is_client_allowed(&its_6000_6000, 0x1234, 0x5678, 0x0001)); + + // DENY only one service instance and ANY_METHOD (0x01 - 0xFFFF) policy + EXPECT_FALSE(its_security->is_client_allowed(&its_7000_7000, 0x1234, 0x5678, 0xFFFF)); + EXPECT_FALSE(its_security->is_client_allowed(&its_7000_7000, 0x1234, 0x5678, 0x0001)); + + // allow only one service instance and ANY_METHOD policy + EXPECT_TRUE(its_security->is_client_allowed(&its_8000_8000, 0x1234, 0x5678, 0xFFFF)); + EXPECT_TRUE(its_security->is_client_allowed(&its_8000_8000, 0x1234, 0x5678, 0x0001)); + + // check request service + EXPECT_TRUE(its_security->is_client_allowed(&its_5000_5000, 0x1234, 0x5678, 0x00, true)); + EXPECT_FALSE(its_security->is_client_allowed(&its_6000_6000, 0x1234, 0x5678, 0x00, true)); + EXPECT_FALSE(its_security->is_client_allowed(&its_7000_7000, 0x1234, 0x5678, 0x00, true)); + EXPECT_TRUE(its_security->is_client_allowed(&its_7000_7000, 0x2222, 0x5678, 0x00, true)); + EXPECT_TRUE(its_security->is_client_allowed(&its_8000_8000, 0x1234, 0x5678, 0x00, true)); + + EXPECT_TRUE(its_security->check_credentials(0x1277, &its_1000_1000)); + EXPECT_FALSE(its_security->check_credentials(0x1277, &its_1001_1001)); + EXPECT_TRUE(its_security->check_credentials(0x1278, &its_1000_1000)); + EXPECT_TRUE(its_security->check_credentials(0x1278, &its_9000_9000)); + + // Security update / removal whitelist + EXPECT_TRUE(its_security->is_policy_removal_allowed(1000)); + EXPECT_TRUE(its_security->is_policy_removal_allowed(1001)); + EXPECT_TRUE(its_security->is_policy_removal_allowed(1008)); + EXPECT_TRUE(its_security->is_policy_removal_allowed(2000)); + EXPECT_TRUE(its_security->is_policy_removal_allowed(3000)); + + EXPECT_FALSE(its_security->is_policy_removal_allowed(2001)); + EXPECT_FALSE(its_security->is_policy_removal_allowed(3001)); + + // create a valid policy object that is on whitelist and test is_policy_update_allowed method + std::shared_ptr _policy(std::make_shared()); + uint32_t its_uid = 1000; + uint32_t its_gid = 1000; + + // policy elements + boost::icl::discrete_interval its_uids(its_uid, its_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(its_gid, its_gid)); + + _policy->credentials_ += std::make_pair(its_uids, its_gids); + _policy->allow_who_ = true; + _policy->allow_what_ = true; + + vsomeip::service_t its_service(0x1234); + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map > its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + _policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + its_service, its_service, + boost::icl::interval_bounds::closed()), + its_instances_methods); + EXPECT_TRUE(its_security->is_policy_update_allowed(1000, _policy)); + + // test valid policy that holds a single service id which is whitelisted + vsomeip::service_t its_second_service(0x7800); + _policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + its_second_service, its_second_service, + boost::icl::interval_bounds::closed()), + its_instances_methods); + EXPECT_TRUE(its_security->is_policy_update_allowed(1000, _policy)); + + // test invalid UID which is not whitelisted + EXPECT_FALSE(its_security->is_policy_update_allowed(2002, _policy)); + + // test invalid policy that additionally holds a service id which is not whitelisted + vsomeip::service_t its_third_service(0x8888); + _policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + its_third_service, its_third_service, + boost::icl::interval_bounds::closed()), + its_instances_methods); + EXPECT_FALSE(its_security->is_policy_update_allowed(1000, _policy)); +#endif // !VSOMEIP_DISABLE_SECURITY + + // TCP connection setting: + // max TCP connect time / max allowed number of aborted TCP endpoint restarts until forced restart + EXPECT_EQ(its_configuration->get_max_tcp_connect_time(), 10000u); + EXPECT_EQ(its_configuration->get_max_tcp_restart_aborts(), 15u); + + // 6. Service discovery + bool enabled = its_configuration->is_sd_enabled(); + std::string protocol = its_configuration->get_sd_protocol(); + uint16_t port = its_configuration->get_sd_port(); + std::string multicast = its_configuration->get_sd_multicast(); + + uint32_t initial_delay_min = its_configuration->get_sd_initial_delay_min(); + uint32_t initial_delay_max = its_configuration->get_sd_initial_delay_max(); + int32_t repetitions_base_delay = its_configuration->get_sd_repetitions_base_delay(); + uint8_t repetitions_max = its_configuration->get_sd_repetitions_max(); + vsomeip::ttl_t ttl = its_configuration->get_sd_ttl(); + int32_t cyclic_offer_delay = its_configuration->get_sd_cyclic_offer_delay(); + int32_t request_response_delay = its_configuration->get_sd_request_response_delay(); + + EXPECT_TRUE(check(enabled, _expected_enabled, "SD ENABLED")); + EXPECT_TRUE(check(protocol, _expected_protocol, "SD PROTOCOL")); + EXPECT_TRUE(check(multicast, _expected_multicast, "SD MULTICAST")); + EXPECT_TRUE(check(port, _expected_port, "SD PORT")); + + EXPECT_TRUE(check(initial_delay_min, _expected_initial_delay_min, "SD INITIAL DELAY MIN")); + EXPECT_TRUE(check(initial_delay_max, _expected_initial_delay_max, "SD INITIAL DELAY MAX")); + EXPECT_TRUE(check(repetitions_base_delay, _expected_repetitions_base_delay, "SD REPETITION BASE DELAY")); + EXPECT_TRUE(check(repetitions_max,_expected_repetitions_max, "SD REPETITION MAX")); + EXPECT_TRUE(check(ttl, _expected_ttl, "SD TTL")); + EXPECT_TRUE(check(cyclic_offer_delay, static_cast(_expected_cyclic_offer_delay), "SD CYCLIC OFFER DELAY")); + EXPECT_TRUE(check(request_response_delay, static_cast(_expected_request_response_delay), "SD RESPONSE REQUEST DELAY")); + EXPECT_EQ(1000u, its_configuration->get_sd_offer_debounce_time()); + + ASSERT_TRUE(vsomeip::plugin_manager_impl::get()->unload_plugin(vsomeip::plugin_type_e::CONFIGURATION_PLUGIN)); +} + +TEST(configuration_test, check_config_file) { + // Check current configuration file format + check_file(CONFIGURATION_FILE, + EXPECTED_UNICAST_ADDRESS, + EXPECTED_HAS_CONSOLE, + EXPECTED_HAS_FILE, + EXPECTED_HAS_DLT, + EXPECTED_VERSION_LOGGING_ENABLED, + EXPECTED_VERSION_LOGGING_INTERVAL, + EXPECTED_APPLICATION_MAX_DISPATCHERS, + EXPECTED_APPLICATION_MAX_DISPATCH_TIME, + EXPECTED_APPLICATION_THREADS, + EXPECTED_APPLICATION_REQUEST_DEBOUNCE_TIME, + EXPECTED_LOGFILE, + EXPECTED_LOGLEVEL, + EXPECTED_UNICAST_ADDRESS_1234_0022, + EXPECTED_RELIABLE_PORT_1234_0022, + EXPECTED_UNRELIABLE_PORT_1234_0022, + EXPECTED_UNICAST_ADDRESS_1234_0023, + EXPECTED_RELIABLE_PORT_1234_0023, + EXPECTED_UNRELIABLE_PORT_1234_0023, + EXPECTED_UNICAST_ADDRESS_2277_0022, + EXPECTED_RELIABLE_PORT_2277_0022, + EXPECTED_UNRELIABLE_PORT_2277_0022, + EXPECTED_UNICAST_ADDRESS_2266_0022, + EXPECTED_RELIABLE_PORT_2266_0022, + EXPECTED_UNRELIABLE_PORT_2266_0022, + EXPECTED_UNICAST_ADDRESS_4466_0321, + EXPECTED_RELIABLE_PORT_4466_0321, + EXPECTED_UNRELIABLE_PORT_4466_0321, + EXPECTED_SD_ENABLED, + EXPECTED_SD_PROTOCOL, + EXPECTED_SD_MULTICAST, + EXPECTED_SD_PORT, + EXPECTED_INITIAL_DELAY_MIN, + EXPECTED_INITIAL_DELAY_MAX, + EXPECTED_REPETITIONS_BASE_DELAY, + EXPECTED_REPETITIONS_MAX, + EXPECTED_TTL, + EXPECTED_CYCLIC_OFFER_DELAY, + EXPECTED_REQUEST_RESPONSE_DELAY); +} + +TEST(configuration_test, check_deprecated_config_file) { + // Check deprecated configuration file format + check_file(DEPRECATED_CONFIGURATION_FILE, + EXPECTED_UNICAST_ADDRESS, + EXPECTED_HAS_CONSOLE, + EXPECTED_HAS_FILE, + EXPECTED_HAS_DLT, + EXPECTED_VERSION_LOGGING_ENABLED, + EXPECTED_VERSION_LOGGING_INTERVAL, + EXPECTED_APPLICATION_MAX_DISPATCHERS, + EXPECTED_APPLICATION_MAX_DISPATCH_TIME, + EXPECTED_APPLICATION_THREADS, + EXPECTED_APPLICATION_REQUEST_DEBOUNCE_TIME, + EXPECTED_LOGFILE, + EXPECTED_LOGLEVEL, + EXPECTED_UNICAST_ADDRESS_1234_0022, + EXPECTED_RELIABLE_PORT_1234_0022, + EXPECTED_UNRELIABLE_PORT_1234_0022, + EXPECTED_UNICAST_ADDRESS_1234_0023, + EXPECTED_RELIABLE_PORT_1234_0023, + EXPECTED_UNRELIABLE_PORT_1234_0023, + EXPECTED_UNICAST_ADDRESS_2277_0022, + EXPECTED_RELIABLE_PORT_2277_0022, + EXPECTED_UNRELIABLE_PORT_2277_0022, + EXPECTED_UNICAST_ADDRESS_2266_0022, + EXPECTED_RELIABLE_PORT_2266_0022, + EXPECTED_UNRELIABLE_PORT_2266_0022, + EXPECTED_UNICAST_ADDRESS_4466_0321, + EXPECTED_RELIABLE_PORT_4466_0321, + EXPECTED_UNRELIABLE_PORT_4466_0321, + EXPECTED_SD_ENABLED, + EXPECTED_SD_PROTOCOL, + EXPECTED_SD_MULTICAST, + EXPECTED_SD_PORT, + EXPECTED_DEPRECATED_INITIAL_DELAY_MIN, + EXPECTED_DEPRECATED_INITIAL_DELAY_MAX, + EXPECTED_DEPRECATED_REPETITIONS_BASE_DELAY, + EXPECTED_DEPRECATED_REPETITIONS_MAX, + EXPECTED_DEPRECATED_TTL, + EXPECTED_CYCLIC_OFFER_DELAY, + EXPECTED_DEPRECATED_REQUEST_RESPONSE_DELAY); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/configuration_tests/configuration-test.json b/test/network_tests/configuration_tests/configuration-test.json new file mode 100644 index 0000000..e18026e --- /dev/null +++ b/test/network_tests/configuration_tests/configuration-test.json @@ -0,0 +1,492 @@ +{ + "unicast" : "10.0.2.15", + "diagnosis" : "0x55", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : { "enable" : "true", "path" : "/home/someip/another-file.log" }, + "dlt" : "false", + "version" : { + "enable" : "false", + "interval" : "15" + } + }, + "watchdog" : + { + "enable" : "true", + "timeout" : "1234", + "allowed_missing_pongs" : "7" + }, + "file-permissions" : + { + "permissions-shm" : "0444", + "permissions-uds" : "0222" + }, + "supports_selective_broadcasts" : + [ + "160.160.160.160" + ], + "tracing" : + { + "enable" : "true", + "sd_enable" : "true", + "channels" : + [ + { + "name" : "testname", + "id" : "testid" + }, + { + "name" : "testname2", + "id" : "testid2" + }, + { + "name" : "testname3", + "id" : "testid3" + }, + { + "name" : "testname4", + "id" : "testid4" + } + ], + "filters" : + [ + { + "channel" : "testname", + "matches" : [ "0x1111", 2222 ], + "type" : "positive" + }, + { + "channel" : "testname2", + "matches" : [ "0x3333", 4444 ], + "type" : "negative" + }, + { + "channel" : "testname3", + "matches" : [ "0x1111", { "service" : "0x3333", "instance" : "0xffff", "method" : "0x8888" } ], + "type" : "negative" + }, + { + "channel" : "testname4", + "matches" : + { + "from" : + { + "service" : "0x1111", + "instance" : "0x0001", + "method" : "0xffff" + }, + "to" : + { + "service" : "0x3333", + "instance" : "0x0001", + "method" : "0x8888" + } + }, + "type" : "negative" + } + ] + }, + "applications" : + [ + { + "name" : "my_application", + "id" : "0x7788", + "max_dispatchers" : "25", + "max_dispatch_time" : "1234", + "threads" : "12", + "request_debounce_time" : "5000", + "plugins" : + [ + { + "name" : "testlibraryname", + "type" : "application_plugin" + }, + { + "name" : "wrongtestlibraryname", + "type" : "intentionally_wrong_plugin" + } + ] + }, + { + "name" : "other_application", + "id" : "0x9933", + "threads" : "0", + "threads" : "256", + "request_debounce_time" : "10001" + } + ], + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x0022", + "unicast" : "local", + "reliable" : { "port" : "30506", "enable-magic-cookies" : "true" }, + "unreliable" : "31000", + "events" : + [ + { + "event" : "0x0778", + "is_field" : "false" + }, + { + "event" : "0x779", + "is_field" : "true" + }, + { + "event" : "0x77A", + "is_field" : "false" + } + ], + "eventgroups" : + [ + { + "eventgroup" : "0x4567", + "multicast" : "225.226.227.228", + "events" : [ "0x778", "0x779" ] + }, + { + "eventgroup" : "0x4569", + "multicast" : "225.227.227.228", + "events" : [ "0x779", "0x77A" ] + }, + { + "eventgroup" : "0x4569", + "multicast" : "225.222.227.228", + "events" : [ "0x778", "0x77A" ] + } + ] + }, + { + "service" : "0x1234", + "instance" : "0x0023", + "reliable" : "30503" + }, + { + "service" : "0x2277", + "instance" : "0x0022", + "reliable" : { "port" : "30505" }, + "unreliable" : "31001" + }, + { + "service" : "0x2266", + "instance" : "0x0022", + "reliable" : "30505", + "unreliable" : "30507" + }, + { + "service" : "0x4466", + "instance" : "0x0321", + "unicast" : "10.0.2.23", + "reliable" : "30506", + "unreliable" : "30444" + }, + { + "service" : "0x3333", + "instance" : "0x1" + }, + { + "service" : "0x7809", + "instance" : "0x1", + "multicast" : + { + "address" : "224.212.244.225", + "port" : "1234" + }, + "eventgroups" : + [ + { + "eventgroup" : "0x1111", + "threshold" : "8", + "is_multicast" : "true", + "events" : [ "0x778", "0x77A" ] + } + ] + }, + { + "service" : "0x3555", + "instance" : "0x1", + "protocol" : "other" + } + ], + "internal_services" : + [ + { + "first" : "0xF100", + "last" : "0xF109" + }, + { + "first" : { + "service" : "0xF300", + "instance" : "0x1" + }, + "last" : { + "service" : "0xF300", + "instance" : "0x10" + } + } + ], + "clients" : + [ + { + "reliable_remote_ports" : { "first" : "30500", "last" : "30599" }, + "unreliable_remote_ports" : { "first" : "30500", "last" : "30599" }, + "reliable_client_ports" : { "first" : "30491", "last" : "30499" }, + "unreliable_client_ports" : { "first" : "30491", "last" : "30499" } + }, + { + "reliable_remote_ports" : { "first" : "31500", "last" : "31599" }, + "unreliable_remote_ports" : { "first" : "31500", "last" : "31599" }, + "reliable_client_ports" : { "first" : "31491", "last" : "31499" }, + "unreliable_client_ports" : { "first" : "31491", "last" : "31499" } + }, + { + "reliable_remote_ports" : { "first" : "32500", "last" : "32599" }, + "unreliable_remote_ports" : { "first" : "32500", "last" : "32599" }, + "reliable_client_ports" : { "first" : "32491", "last" : "32499" }, + "unreliable_client_ports" : { "first" : "32491", "last" : "32499" } + }, + { + "service" : "0x8888", + "instance" : "0x1", + "unreliable" : [ "0x11", "0x10" ], + "reliable" : [ "0x11", "0x10" ] + }, + { + "service" : "8888", + "instance" : "1", + "unreliable" : [ 40000, 40001 ], + "reliable" : [ 40000, 40001 ] + } + ], + "tcp-restart-aborts-max" : "15", + "tcp-connect-time-max" : "10000", + "max-payload-size-local" : "15000", + "max-payload-size-reliable" : "17000", + "buffer-shrink-threshold" : "11", + "payload-sizes": + [ + { + "unicast":"10.10.10.10", + "ports": + [ + { + "port":"7777", + "max-payload-size":"14999" + } + ] + }, + { + "unicast":"10.10.10.11", + "ports": + [ + { + "port":"7778", + "max-payload-size":"15001" + } + ] + } + ], + "security" : + { + "check_credentials" : "true", + "policies" : + [ + { + "credentials" : { "uid" : "1000", "gid" : "1000" }, + "allow" : + { + "offers": + [ + { + "service" : "0x1234", + "instance" : "0x5678" + }, + { + "service" : "0x1235", + "instance" : "0x5678" + }, + { + "service" : "0x1236", + "instances" : [{ "first" : "0x5676", "last" : "0x5677"}, "0x5678"] + } + ] + } + }, + { + "credentials" : { "uid" : "2000", "gid" : "2000" }, + "allow" : + { + "requests": + [ + { + "service" : "0x1234", + "instances" : [ + { + "ids" : ["0x5678", { "first" : "0x5679", "last" : "0x5699"}], + "methods" : [ "0x0001", { "first" : "0x8001", "last" : "0x8006" }] + } + ] + }, + { + "service" : "0x1237", + "instances" : [ + { + "ids" : ["0x5678"], + "methods" : "any" + } + ] + }, + { + "service" : "0x1238", + "instances" : [ + { + "ids" : "any", + "methods" : ["0x0001"] + } + ] + } + ] + } + }, + { + "credentials" : { "uid" : "4000", "gid" : "4000" }, + "deny" : + { + "requests": + [ + { + "service" : "0x1234", + "instances" : [ + { + "ids" : ["0x5678", { "first" : "0x5679", "last" : "0x5699"}], + "methods" : [ "0x0002", { "first" : "0x9001", "last" : "0x9006" }] + } + ] + } + ], + "offers": + [ + { + "service" : "0x1234", + "instance" : "0x5678" + }, + { + "service" : "0x1235", + "instance" : "0x5678" + }, + { + "service" : "0x1236", + "instances" : [{ "first" : "0x5675", "last" : "0x5677"}, "0x5678"] + } + ] + } + }, + { + "credentials" : { "uid" : "5000", "gid" : "5000" }, + "deny" : + { + } + }, + { + "credentials" : { "uid" : "6000", "gid" : "6000" }, + "allow" : + { + } + }, + { + "credentials" : { "uid" : "7000", "gid" : "7000" }, + "deny" : + { + "requests": + [ + { + "service" : "0x1234", + "instances" : [ + { + "ids" : ["0x5678"], + "methods" : "any" + } + ] + } + ] + } + }, + { + "credentials" : { "uid" : "8000", "gid" : "8000" }, + "allow" : + { + "requests": + [ + { + "service" : "0x1234", + "instances" : [ + { + "ids" : ["0x5678"], + "methods" : "any" + } + ] + } + ] + } + }, + { + "credentials" : { + "allow": [ + { + "uid": [ + "9000" + ], + "gid": [ + "9000" + ] + } + ] + }, + "deny" : + { + } + } + ] + }, + "security-update-whitelist" : + { + "uids" : + [ + {"first" : "1000", "last" : "1008"}, + {"first" : "1100", "last" : "1200"}, + "2000", + "3000" + ], + "services" : + [ + {"first" : "0x1234", "last" : "0x1238"}, + {"first" : "0x2000", "last" : "0x2500"}, + "0x7800" + ], + "check-whitelist" : "true" + }, + "routing" : "my_application", + "routing-credentials" : + { + "uid" : "0x123", + "gid" : "0x456" + }, + "service-discovery" : + { + "enable" : "true", + "protocol" : "udp", + "multicast" : "224.212.244.223", + "port" : "30666", + "initial_delay_min" : "1234", + "initial_delay_max" : "2345", + "repetitions_base_delay" : "4242", + "repetitions_max" : "4", + "ttl" : "13", + "cyclic_offer_delay" : "2132", + "request_response_delay" : "1111", + "offer_debounce_time" : "1000" + } +} diff --git a/test/network_tests/cpu_load_tests/conf/cpu_load_test_client_master.json.in b/test/network_tests/cpu_load_tests/conf/cpu_load_test_client_master.json.in new file mode 100644 index 0000000..ec9dcd7 --- /dev/null +++ b/test/network_tests/cpu_load_tests/conf/cpu_load_test_client_master.json.in @@ -0,0 +1,38 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/var/log/vsomeip.log" + }, + + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "cpu_load_test_client", + "id" : "0x2222" + } + ], + "npdu-default-timings" : { + "debounce-time-request" : "0", + "debounce-time-response" : "0", + "max-retention-time-request" : "0", + "max-retention-time-response" : "0" + }, + "routing" : "cpu_load_test_client", + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp" + } +} diff --git a/test/network_tests/cpu_load_tests/conf/cpu_load_test_client_slave.json.in b/test/network_tests/cpu_load_tests/conf/cpu_load_test_client_slave.json.in new file mode 100644 index 0000000..4da82f4 --- /dev/null +++ b/test/network_tests/cpu_load_tests/conf/cpu_load_test_client_slave.json.in @@ -0,0 +1,38 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/var/log/vsomeip.log" + }, + + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "cpu_load_test_client", + "id" : "0x2222" + } + ], + "npdu-default-timings" : { + "debounce-time-request" : "0", + "debounce-time-response" : "0", + "max-retention-time-request" : "0", + "max-retention-time-response" : "0" + }, + "routing" : "cpu_load_test_client", + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp" + } +} diff --git a/test/network_tests/cpu_load_tests/conf/cpu_load_test_service_master.json.in b/test/network_tests/cpu_load_tests/conf/cpu_load_test_service_master.json.in new file mode 100644 index 0000000..da34e22 --- /dev/null +++ b/test/network_tests/cpu_load_tests/conf/cpu_load_test_service_master.json.in @@ -0,0 +1,51 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/tmp/vsomeip.log" + }, + + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "cpu_load_test_service", + "id" : "0x1111" + } + ], + + "services" : + [ + { + "service" : "0x1111", + "instance" : "0x1", + "unreliable" : "30510", + "reliable" : + { + "port" : "30510", + "enable-magic-cookies" : "false" + } + } + ], + "npdu-default-timings" : { + "debounce-time-request" : "0", + "debounce-time-response" : "0", + "max-retention-time-request" : "0", + "max-retention-time-response" : "0" + }, + "routing" : "cpu_load_test_service", + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp" + } +} diff --git a/test/network_tests/cpu_load_tests/conf/cpu_load_test_service_slave.json.in b/test/network_tests/cpu_load_tests/conf/cpu_load_test_service_slave.json.in new file mode 100644 index 0000000..389aea0 --- /dev/null +++ b/test/network_tests/cpu_load_tests/conf/cpu_load_test_service_slave.json.in @@ -0,0 +1,51 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/tmp/vsomeip.log" + }, + + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "cpu_load_test_service", + "id" : "0x1111" + } + ], + + "services" : + [ + { + "service" : "0x1111", + "instance" : "0x1", + "unreliable" : "30510", + "reliable" : + { + "port" : "30510", + "enable-magic-cookies" : "false" + } + } + ], + "npdu-default-timings" : { + "debounce-time-request" : "0", + "debounce-time-response" : "0", + "max-retention-time-request" : "0", + "max-retention-time-response" : "0" + }, + "routing" : "cpu_load_test_service", + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp" + } +} diff --git a/test/network_tests/cpu_load_tests/cpu_load_measurer.cpp b/test/network_tests/cpu_load_tests/cpu_load_measurer.cpp new file mode 100644 index 0000000..d4360b3 --- /dev/null +++ b/test/network_tests/cpu_load_tests/cpu_load_measurer.cpp @@ -0,0 +1,159 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "cpu_load_measurer.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +cpu_load_measurer::~cpu_load_measurer() { +} + +cpu_load_measurer::cpu_load_measurer(std::uint32_t _pid) : + pid_(_pid), + jiffies_complete_start_(0), + jiffies_idle_start_(0), + jiffies_complete_stop_(0), + jiffies_idle_stop_(0), + clock_ticks_(0), + jiffies_passed_pid_start_(0), + jiffies_passed_pid_stop_(0), + cpu_load_pid_(0.0), + cpu_load_overall_(0.0), + cpu_load_pid_wo_idle_(0.0) { +} + +void cpu_load_measurer::start() { + // reset everything + jiffies_complete_start_ = 0; + jiffies_idle_start_ = 0; + jiffies_complete_stop_ = 0; + jiffies_idle_stop_ = 0; + clock_ticks_ = 0; + jiffies_passed_pid_start_ = 0; + jiffies_passed_pid_stop_ = 0; + cpu_load_pid_= 0.0; + cpu_load_overall_ = 0.0; + cpu_load_pid_wo_idle_ = 0.0; + //start + jiffies_complete_start_ = read_proc_stat(&jiffies_idle_start_); + jiffies_passed_pid_start_ = read_proc_pid_stat(); +} + +void cpu_load_measurer::stop() { + jiffies_complete_stop_ = read_proc_stat(&jiffies_idle_stop_); + jiffies_passed_pid_stop_ = read_proc_pid_stat(); + if(jiffies_complete_stop_ < jiffies_complete_start_ || jiffies_passed_pid_stop_ < jiffies_passed_pid_start_) { + std::cerr << "Overflow of values in procfs occured, can't calculate load" << std::endl; + exit(0); + } + cpu_load_pid_ = 100.0 + * static_cast(jiffies_passed_pid_stop_ + - jiffies_passed_pid_start_) + / static_cast(jiffies_complete_stop_ + - jiffies_complete_start_); + cpu_load_overall_ = 100.0 + * static_cast((jiffies_complete_stop_ - jiffies_idle_stop_) + - (jiffies_complete_start_ - jiffies_idle_start_)) + / static_cast(jiffies_complete_stop_ + - jiffies_complete_start_); + cpu_load_pid_wo_idle_ = 100.0 + * static_cast(jiffies_passed_pid_stop_ + - jiffies_passed_pid_start_) + / static_cast((jiffies_complete_stop_ - jiffies_idle_stop_) + - (jiffies_complete_start_ - jiffies_idle_start_)); + +} + +void cpu_load_measurer::print_cpu_load() const { + std::cout << "Used Jiffies complete: " + << jiffies_complete_stop_ - jiffies_complete_start_ << " (worked: " + << (jiffies_complete_stop_ - jiffies_idle_stop_) + - (jiffies_complete_start_ - jiffies_idle_start_) + << " idled: " << jiffies_idle_stop_ - jiffies_idle_start_ + << ")" << std::endl; + std::cout << "Used Jiffies of pid " << pid_ << ": " << jiffies_passed_pid_stop_ - jiffies_passed_pid_start_ << std::endl; + std::cout << "Cpu load pid " << pid_ << " [%]: " << cpu_load_pid_ << std::endl; + std::cout << "Overall cpu load[%]: " << cpu_load_overall_ << std::endl; + std::cout << "Load caused by pid " << pid_ << " of overall cpu load [%]:" << cpu_load_pid_wo_idle_ << std::endl; +} + +double cpu_load_measurer::get_cpu_load() const { + return cpu_load_pid_; +} + +std::uint64_t cpu_load_measurer::read_proc_pid_stat() { + std::string path("/proc/" + std::to_string(pid_) + "/stat"); + FILE* f = std::fopen(path.c_str(), "r"); + if(!f) { + std::perror(std::string("Failed to open " + path).c_str()); + exit(1); + } + // see Table 1-4 Contents of the stat files (as of 2.6.30-rc7) + // at https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/filesystems/proc.txt?id=refs/tags/v3.10.98 + // and man proc (for conversion specifier) + std::uint64_t utime(0); + std::uint64_t stime(0); + std::int64_t cutime(0); + std::int64_t cstime(0); + if (std::fscanf(f, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u " + "%lu %lu %ld %ld", // utime, stime, cutime, cstime + &utime, &stime, &cutime, &cstime) == EOF) { + std::cerr << "Failed to read " + path << std::endl; + exit(1); + } + std::fclose(f); + return utime + stime + static_cast(cutime) + + static_cast(cstime); +} + +std::uint64_t cpu_load_measurer::read_proc_stat(std::uint64_t* _idle) { + FILE* f = std::fopen("/proc/stat", "r"); + if(!f) { + std::perror("Failed to open /proc/stat"); + exit(1); + } + + // see 1.8 Miscellaneous kernel statistics in /proc/stat + // at https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/tree/Documentation/filesystems/proc.txt?id=refs/tags/v3.10.98 + std::uint64_t user(0); + std::uint64_t nice(0); + std::uint64_t system(0); + std::uint64_t idle(0); + std::uint64_t iowait(0); + std::uint64_t irq(0); + std::uint64_t softirq(0); + std::uint64_t steal(0); + std::uint64_t guest(0); + std::uint64_t guest_nice(0); + if (std::fscanf(f, "%*s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu", &user, + &nice, &system, &idle, &iowait, &irq, &softirq, &steal, &guest, + &guest_nice) == EOF) { + std::cerr << "Failed to read /proc/stat" << std::endl; + exit(1); + } + std::fclose(f); + *_idle = idle; + return user + nice + system + idle + iowait + irq + softirq + steal + guest + + guest_nice; +} + +bool cpu_load_measurer::read_clock_ticks() { + long val(::sysconf(_SC_CLK_TCK)); + if(val < 0 && errno == EINVAL) { + std::perror(__func__); + return false; + } + clock_ticks_ = static_cast(val); + return true; +} diff --git a/test/network_tests/cpu_load_tests/cpu_load_measurer.hpp b/test/network_tests/cpu_load_tests/cpu_load_measurer.hpp new file mode 100644 index 0000000..dfdcf80 --- /dev/null +++ b/test/network_tests/cpu_load_tests/cpu_load_measurer.hpp @@ -0,0 +1,35 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include + +class cpu_load_measurer { +public: + cpu_load_measurer(std::uint32_t _pid); + virtual ~cpu_load_measurer(); + void start(); + void stop(); + void print_cpu_load() const; + double get_cpu_load() const; + +private: + std::uint64_t read_proc_stat(std::uint64_t* _idle); + std::uint64_t read_proc_pid_stat(); + bool read_clock_ticks(); +private: + std::uint32_t pid_; + std::uint64_t jiffies_complete_start_; + std::uint64_t jiffies_idle_start_; + std::uint64_t jiffies_complete_stop_; + std::uint64_t jiffies_idle_stop_; + std::uint64_t clock_ticks_; + std::uint64_t jiffies_passed_pid_start_; + std::uint64_t jiffies_passed_pid_stop_; + double cpu_load_pid_; + double cpu_load_overall_; + double cpu_load_pid_wo_idle_; +}; diff --git a/test/network_tests/cpu_load_tests/cpu_load_test_client.cpp b/test/network_tests/cpu_load_tests/cpu_load_test_client.cpp new file mode 100644 index 0000000..d1d5104 --- /dev/null +++ b/test/network_tests/cpu_load_tests/cpu_load_test_client.cpp @@ -0,0 +1,390 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include // for isfinite +#include + +#include "cpu_load_test_globals.hpp" +#include +#include "cpu_load_measurer.hpp" + +// for getpid +#include +#include + + +enum protocol_e { + PR_UNKNOWN, + PR_TCP, + PR_UDP +}; + +class cpu_load_test_client +{ +public: + cpu_load_test_client(protocol_e _protocol, std::uint32_t _number_of_calls, + std::uint32_t _payload_size, bool _call_service_sync, + bool _shutdown_service) : + protocol_(_protocol), + app_(vsomeip::runtime::get()->create_application("cpu_load_test_client")), + request_(vsomeip::runtime::get()->create_request(protocol_ == protocol_e::PR_TCP)), + call_service_sync_(_call_service_sync), + shutdown_service_at_end_(_shutdown_service), + sliding_window_size_(_number_of_calls), + wait_for_availability_(true), + is_available_(false), + number_of_calls_(_number_of_calls), + number_of_calls_current_(0), + number_of_sent_messages_(0), + number_of_sent_messages_total_(0), + number_of_acknowledged_messages_(0), + payload_size_(_payload_size), + wait_for_all_msg_acknowledged_(true), + initialized_(false), + sender_(std::bind(&cpu_load_test_client::run, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + initialized_ = true; + app_->register_state_handler( + std::bind(&cpu_load_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, + std::bind(&cpu_load_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(cpu_load_test::service_id, + cpu_load_test::instance_id, + std::bind(&cpu_load_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + VSOMEIP_INFO << "Starting..."; + app_->start(); + } + + ~cpu_load_test_client() { + { + std::lock_guard its_lock(mutex_); + wait_for_availability_ = false; + condition_.notify_one(); + } + { + std::lock_guard its_lock(all_msg_acknowledged_mutex_); + wait_for_all_msg_acknowledged_ = false; + all_msg_acknowledged_cv_.notify_one(); + } + sender_.join(); + } + +private: + void stop() { + VSOMEIP_INFO << "Stopping..."; + // shutdown the service + if(shutdown_service_at_end_) + { + shutdown_service(); + } + app_->clear_all_handler(); + } + + void on_state(vsomeip::state_type_e _state) { + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + app_->request_service(cpu_load_test::service_id, + cpu_load_test::instance_id); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + VSOMEIP_INFO << "Service [" << std::setw(4) << std::setfill('0') + << std::hex << _service << "." << _instance << "] is " + << (_is_available ? "available." : "NOT available."); + + if (cpu_load_test::service_id == _service + && cpu_load_test::instance_id == _instance) { + if (is_available_ && !_is_available) { + is_available_ = false; + } else if (_is_available && !is_available_) { + is_available_ = true; + std::lock_guard its_lock(mutex_); + wait_for_availability_ = false; + condition_.notify_one(); + } + } + } + void on_message(const std::shared_ptr &_response) { + + number_of_acknowledged_messages_++; + ASSERT_EQ(_response->get_service(), cpu_load_test::service_id); + ASSERT_EQ(_response->get_method(), cpu_load_test::method_id); + if(call_service_sync_) + { + // We notify the sender thread every time a message was acknowledged + std::lock_guard lk(all_msg_acknowledged_mutex_); + wait_for_all_msg_acknowledged_ = false; + all_msg_acknowledged_cv_.notify_one(); + } + else + { + // We notify the sender thread only if all sent messages have been acknowledged + if(number_of_acknowledged_messages_ == number_of_calls_current_) + { + std::lock_guard lk(all_msg_acknowledged_mutex_); + number_of_acknowledged_messages_ = 0; + wait_for_all_msg_acknowledged_ = false; + all_msg_acknowledged_cv_.notify_one(); + } + else if(number_of_acknowledged_messages_ % sliding_window_size_ == 0) + { + std::lock_guard lk(all_msg_acknowledged_mutex_); + wait_for_all_msg_acknowledged_ = false; + all_msg_acknowledged_cv_.notify_one(); + } + } + } + + void run() { + std::unique_lock its_lock(mutex_); + while (wait_for_availability_) { + condition_.wait(its_lock); + } + + request_->set_service(cpu_load_test::service_id); + request_->set_instance(cpu_load_test::instance_id); + request_->set_method(cpu_load_test::method_id); + std::shared_ptr payload = vsomeip::runtime::get()->create_payload(); + std::vector payload_data; + payload_data.assign(payload_size_, cpu_load_test::load_test_data); + payload->set_data(payload_data); + request_->set_payload(payload); + + // lock the mutex + for(std::uint32_t i=0; i <= number_of_calls_; i++) { + number_of_calls_current_ = i; + sliding_window_size_ = i; + std::unique_lock lk(all_msg_acknowledged_mutex_); + call_service_sync_ ? send_messages_sync(lk, i) : send_messages_async(lk, i); + } + const double average_load(std::accumulate(results_.begin(), results_.end(), 0.0) / static_cast(results_.size())); + VSOMEIP_INFO << "Sent: " << number_of_sent_messages_total_ + << " messages in total (excluding control messages). This caused: " + << std::fixed << std::setprecision(2) + << average_load << "% load in average (average of " + << results_.size() << " measurements)."; + + std::vector results_no_zero; + for(const auto &v : results_) { + if(v > 0.0) { + results_no_zero.push_back(v); + } + } + const double average_load_no_zero(std::accumulate(results_no_zero.begin(), results_no_zero.end(), 0.0) / static_cast(results_no_zero.size())); + VSOMEIP_INFO << "Sent: " << number_of_sent_messages_total_ + << " messages in total (excluding control messages). This caused: " + << std::fixed << std::setprecision(2) + << average_load_no_zero << "% load in average, if measured " + << "cpu load was greater zero (average of " + << results_no_zero.size() << " measurements)."; + + wait_for_availability_ = true; + + stop(); + if (initialized_) { + app_->stop(); + } + } + + + void send_messages_sync(std::unique_lock& lk, std::uint32_t _messages_to_send) { + cpu_load_measurer c(static_cast(::getpid())); + send_service_start_measuring(true); + c.start(); + for (number_of_sent_messages_ = 0; + number_of_sent_messages_ < _messages_to_send; + number_of_sent_messages_++, number_of_sent_messages_total_++) + { + app_->send(request_); + // wait until the send messages has been acknowledged + while(wait_for_all_msg_acknowledged_) { + all_msg_acknowledged_cv_.wait(lk); + } + wait_for_all_msg_acknowledged_ = true; + } + c.stop(); + send_service_start_measuring(false); + VSOMEIP_DEBUG << "Synchronously sent " << std::setw(4) << std::setfill('0') + << number_of_sent_messages_ << " messages. CPU load [%]: " + << std::fixed << std::setprecision(2) + << (std::isfinite(c.get_cpu_load()) ? c.get_cpu_load() : 0.0); + results_.push_back(std::isfinite(c.get_cpu_load()) ? c.get_cpu_load() : 0.0); + + } + + void send_messages_async(std::unique_lock& lk, std::uint32_t _messages_to_send) { + cpu_load_measurer c(static_cast(::getpid())); + send_service_start_measuring(true); + c.start(); + for (number_of_sent_messages_ = 0; + number_of_sent_messages_ < _messages_to_send; + number_of_sent_messages_++, number_of_sent_messages_total_++) + { + app_->send(request_); + if((number_of_sent_messages_+1) % sliding_window_size_ == 0) + { + // wait until all send messages have been acknowledged + while(wait_for_all_msg_acknowledged_) { + all_msg_acknowledged_cv_.wait(lk); + } + wait_for_all_msg_acknowledged_ = true; + } + } + c.stop(); + send_service_start_measuring(false); + VSOMEIP_DEBUG << "Asynchronously sent " << std::setw(4) << std::setfill('0') + << number_of_sent_messages_ << " messages. CPU load [%]: " + << std::fixed << std::setprecision(2) + << (std::isfinite(c.get_cpu_load()) ? c.get_cpu_load() : 0.0); + results_.push_back(std::isfinite(c.get_cpu_load()) ? c.get_cpu_load() : 0.0); + } + + void send_service_start_measuring(bool _start_measuring) { + std::shared_ptr m = vsomeip::runtime::get()->create_request(protocol_ == protocol_e::PR_TCP); + m->set_service(cpu_load_test::service_id); + m->set_instance(cpu_load_test::instance_id); + _start_measuring ? m->set_method(cpu_load_test::method_id_cpu_measure_start) : m->set_method(cpu_load_test::method_id_cpu_measure_stop); + app_->send(m); + } + + void shutdown_service() { + request_->set_service(cpu_load_test::service_id); + request_->set_instance(cpu_load_test::instance_id); + request_->set_method(cpu_load_test::method_id_shutdown); + app_->send(request_); + } + +private: + protocol_e protocol_; + std::shared_ptr app_; + std::shared_ptr request_; + bool call_service_sync_; + bool shutdown_service_at_end_; + std::uint32_t sliding_window_size_; + std::mutex mutex_; + std::condition_variable condition_; + bool wait_for_availability_; + bool is_available_; + const std::uint32_t number_of_calls_; + std::uint32_t number_of_calls_current_; + std::uint32_t number_of_sent_messages_; + std::uint32_t number_of_sent_messages_total_; + std::uint32_t number_of_acknowledged_messages_; + + std::uint32_t payload_size_; + + bool wait_for_all_msg_acknowledged_; + std::mutex all_msg_acknowledged_mutex_; + std::condition_variable all_msg_acknowledged_cv_; + std::vector results_; + std::atomic initialized_; + std::thread sender_; +}; + + +// this variables are changed via cmdline parameters +static protocol_e protocol(protocol_e::PR_UNKNOWN); +static std::uint32_t number_of_calls(0); +static std::uint32_t payload_size(40); +static bool call_service_sync(true); +static bool shutdown_service(true); + + +TEST(someip_load_test, DISABLED_send_messages_and_measure_cpu_load) +{ + cpu_load_test_client test_client_(protocol, number_of_calls, payload_size, call_service_sync, shutdown_service); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + int i = 0; + while (i < argc) { + if(std::string("--protocol") == std::string(argv[i]) + || std::string("-p") == std::string(argv[i])) { + if(std::string("udp") == std::string(argv[i+1]) || + std::string("UDP") == std::string(argv[i+1])) { + protocol = protocol_e::PR_UDP; + i++; + } else if(std::string("tcp") == std::string(argv[i+1]) || + std::string("TCP") == std::string(argv[i+1])) { + protocol = protocol_e::PR_TCP; + i++; + } + } else if(std::string("--calls") == std::string(argv[i]) + || std::string("-c") == std::string(argv[i])) { + try { + number_of_calls = static_cast(std::stoul(std::string(argv[i+1]), nullptr, 10)); + } catch (const std::exception &e) { + std::cerr << "Please specify a valid value for number of calls" << std::endl; + return(EXIT_FAILURE); + } + i++; + } else if(std::string("--mode") == std::string(argv[i]) + || std::string("-m") == std::string(argv[i])) { + if(std::string("sync") == std::string(argv[i+1]) || + std::string("SYNC") == std::string(argv[i+1])) { + call_service_sync = true; + i++; + } else if(std::string("async") == std::string(argv[i+1]) || + std::string("ASYNC") == std::string(argv[i+1])) { + call_service_sync = false; + i++; + } + } else if(std::string("--payload-size") == std::string(argv[i]) + || std::string("-pl") == std::string(argv[i])) { + try { + payload_size = static_cast(std::stoul(std::string(argv[i+1]), nullptr, 10)); + } catch (const std::exception &e) { + std::cerr << "Please specify a valid values for payload size" << std::endl; + return(EXIT_FAILURE); + } + i++; + } else if(std::string("--help") == std::string(argv[i]) + || std::string("-h") == std::string(argv[i])) { + std::cout << "Available options:" << std::endl; + std::cout << "--protocol|-p: valid values TCP or UDP" << std::endl; + std::cout << "--calls|-c: number of message calls to do" << std::endl; + std::cout << "--mode|-m: mode sync or async" << std::endl; + std::cout << "--payload-size|-pl: payload size in Bytes default: 40" << std::endl; + } + i++; + } + + if(protocol == protocol_e::PR_UNKNOWN) { + std::cerr << "Please specify valid protocol mode, see --help" << std::endl; + return(EXIT_FAILURE); + } + if(!number_of_calls) { + std::cerr << "Please specify valid number of calls, see --help" << std::endl; + return(EXIT_FAILURE); + } + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/cpu_load_tests/cpu_load_test_globals.hpp b/test/network_tests/cpu_load_tests/cpu_load_test_globals.hpp new file mode 100644 index 0000000..e6897e3 --- /dev/null +++ b/test/network_tests/cpu_load_tests/cpu_load_test_globals.hpp @@ -0,0 +1,18 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +namespace cpu_load_test { + +static constexpr vsomeip::service_t service_id(0x1111); +static constexpr vsomeip::instance_t instance_id(0x1); +static constexpr vsomeip::method_t method_id(0x1111); +static constexpr vsomeip::byte_t load_test_data(0xDD); +static constexpr vsomeip::length_t default_payload_length(40); +static constexpr vsomeip::method_t method_id_shutdown(0x7777); +static constexpr vsomeip::method_t method_id_cpu_measure_start(0x8888); +static constexpr vsomeip::method_t method_id_cpu_measure_stop(0x9999); +} diff --git a/test/network_tests/cpu_load_tests/cpu_load_test_master_starter.sh b/test/network_tests/cpu_load_tests/cpu_load_test_master_starter.sh new file mode 100755 index 0000000..30010c2 --- /dev/null +++ b/test/network_tests/cpu_load_tests/cpu_load_test_master_starter.sh @@ -0,0 +1,75 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +FAIL=0 + +export VSOMEIP_CONFIGURATION=cpu_load_test_client_master.json +./cpu_load_test_client --protocol UDP --calls 1000 & +TEST_CLIENT_PID=$! +sleep 1 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting cpu load test on slave LXC" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP 'bash -ci "set -m; cd \$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./cpu_load_test_slave_starter.sh"' & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./cpu_load_test_slave_starter.sh" & +else +cat < + +#include + +#include +#include +#include +#include +#include +#include // for isfinite + +#include "cpu_load_test_globals.hpp" +#include +#include "cpu_load_measurer.hpp" + +// for getpid +#include +#include + +class cpu_load_test_service +{ +public: + cpu_load_test_service() : + app_(vsomeip::runtime::get()->create_application("cpu_load_test_service")), + is_registered_(false), + blocked_(false), + number_of_received_messages_(0), + number_of_received_messages_total_(0), + load_measurer_(static_cast(::getpid())), + offer_thread_(std::bind(&cpu_load_test_service::run, this)) + { + } + + ~cpu_load_test_service() { + { + std::lock_guard its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); + } + offer_thread_.join(); + } + + bool init() + { + std::lock_guard its_lock(mutex_); + + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + app_->register_message_handler(cpu_load_test::service_id, + cpu_load_test::instance_id, cpu_load_test::method_id, + std::bind(&cpu_load_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler(cpu_load_test::service_id, + cpu_load_test::instance_id, cpu_load_test::method_id_shutdown, + std::bind(&cpu_load_test_service::on_message_shutdown, this, + std::placeholders::_1)); + app_->register_message_handler(cpu_load_test::service_id, + cpu_load_test::instance_id, cpu_load_test::method_id_cpu_measure_start, + std::bind(&cpu_load_test_service::on_message_start_measuring, this, + std::placeholders::_1)); + app_->register_message_handler(cpu_load_test::service_id, + cpu_load_test::instance_id, cpu_load_test::method_id_cpu_measure_stop, + std::bind(&cpu_load_test_service::on_message_stop_measuring, this, + std::placeholders::_1)); + app_->register_state_handler( + std::bind(&cpu_load_test_service::on_state, this, + std::placeholders::_1)); + return true; + } + + void start() + { + VSOMEIP_INFO << "Starting..."; + app_->start(); + } + + void stop() + { + VSOMEIP_INFO << "Stopping..."; + app_->stop_offer_service(cpu_load_test::service_id, cpu_load_test::instance_id); + app_->clear_all_handler(); + app_->stop(); + } + + void on_state(vsomeip::state_type_e _state) + { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : + "deregistered."); + + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + if(!is_registered_) + { + is_registered_ = true; + std::lock_guard its_lock(mutex_); + blocked_ = true; + // "start" the run method thread + condition_.notify_one(); + } + } + else + { + is_registered_ = false; + } + } + + void on_message(const std::shared_ptr& _request) + { + number_of_received_messages_++; + number_of_received_messages_total_++; + // send response + app_->send(vsomeip::runtime::get()->create_response(_request)); + } + + void on_message_start_measuring(const std::shared_ptr& _request) + { + (void)_request; + load_measurer_.start(); + } + + void on_message_stop_measuring(const std::shared_ptr& _request) + { + (void)_request; + load_measurer_.stop(); + VSOMEIP_DEBUG << "Received " << std::setw(4) << std::setfill('0') + << number_of_received_messages_ << " messages. CPU load [%]: " + << std::fixed << std::setprecision(2) + << (std::isfinite(load_measurer_.get_cpu_load()) ? load_measurer_.get_cpu_load() : 0.0); + results_.push_back(std::isfinite(load_measurer_.get_cpu_load()) ? load_measurer_.get_cpu_load() : 0.0); + number_of_received_messages_ = 0; + } + + void on_message_shutdown( + const std::shared_ptr& _request) + { + (void)_request; + VSOMEIP_INFO << "Shutdown method was called, going down now."; + const double average_load(std::accumulate(results_.begin(), results_.end(), 0.0) / static_cast(results_.size())); + VSOMEIP_INFO << "Received: " << number_of_received_messages_total_ + << " in total (excluding control messages). This caused: " + << std::fixed << std::setprecision(2) + << average_load << "% load in average (average of " + << results_.size() << " measurements)."; + + std::vector results_no_zero; + for(const auto &v : results_) { + if(v > 0.0) { + results_no_zero.push_back(v); + } + } + const double average_load_no_zero(std::accumulate(results_no_zero.begin(), results_no_zero.end(), 0.0) / static_cast(results_no_zero.size())); + VSOMEIP_INFO << "Sent: " << number_of_received_messages_total_ + << " messages in total (excluding control messages). This caused: " + << std::fixed << std::setprecision(2) + << average_load_no_zero << "% load in average, if measured cpu load " + << "was greater zero (average of " + << results_no_zero.size() << " measurements)."; + stop(); + } + + void run() + { + std::unique_lock its_lock(mutex_); + while (!blocked_) { + condition_.wait(its_lock); + } + + app_->offer_service(cpu_load_test::service_id, cpu_load_test::instance_id); + } + +private: + std::shared_ptr app_; + bool is_registered_; + + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + std::uint32_t number_of_received_messages_; + std::uint32_t number_of_received_messages_total_; + cpu_load_measurer load_measurer_; + std::vector results_; + std::thread offer_thread_; +}; + + +TEST(someip_payload_test, DISABLED_send_response_for_every_request) +{ + cpu_load_test_service test_service; + if (test_service.init()) { + test_service.start(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/cpu_load_tests/cpu_load_test_slave_starter.sh b/test/network_tests/cpu_load_tests/cpu_load_test_slave_starter.sh new file mode 100755 index 0000000..83ef19d --- /dev/null +++ b/test/network_tests/cpu_load_tests/cpu_load_test_slave_starter.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +FAIL=0 + +export VSOMEIP_CONFIGURATION=cpu_load_test_service_slave.json +./cpu_load_test_service & + +# Wait until all applications are finished +for job in $(jobs -p) +do + # Fail gets incremented if one of the binaries exits + # with a non-zero exit code + wait $job || FAIL=$(($FAIL+1)) +done + +cat < +#include + +#include + +#include "debounce_test_client.hpp" + +static std::vector > > payloads__; + + +debounce_test_client::debounce_test_client(debounce_test_id_e _test_id) + : test_id_(_test_id), + index_(0), + is_available_(false), + runner_(std::bind(&debounce_test_client::run, this)), + app_(vsomeip::runtime::get()->create_application("debounce_test_client")) { +} + +bool +debounce_test_client::init() { + + bool its_result = app_->init(); + if (its_result) { + app_->register_availability_handler( + DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + std::bind(&debounce_test_client::on_availability, this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3), + DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + app_->register_message_handler( + DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, vsomeip::ANY_EVENT, + std::bind(&debounce_test_client::on_message, this, + std::placeholders::_1)); + app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENT, { DEBOUNCE_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENT_2, { DEBOUNCE_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENT_4, { DEBOUNCE_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, DEBOUNCE_EVENT); + app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, DEBOUNCE_EVENT_2); + app_->subscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENTGROUP, DEBOUNCE_MAJOR, DEBOUNCE_EVENT_4); + } + return (its_result); +} + +void +debounce_test_client::start() { + + app_->start(); +} + +void +debounce_test_client::stop() { + + app_->stop(); +} + +void +debounce_test_client::run() { + + { + std::unique_lock its_lock(run_mutex_); + while (!is_available_) { + auto its_status + = run_condition_.wait_for(its_lock, std::chrono::milliseconds(15000)); + EXPECT_EQ(its_status, std::cv_status::no_timeout); + if (its_status == std::cv_status::timeout) { + VSOMEIP_ERROR << __func__ << ": Debounce service did not become available after 15s."; + stop(); + return; + } + } + } + + VSOMEIP_INFO << __func__ << ": Running test."; + run_test(); + + unsubscribe_all(); + + VSOMEIP_INFO << __func__ << ": Stopping the service."; + stop_service(); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + stop(); +} + +void +debounce_test_client::wait() { + + if (runner_.joinable()) + runner_.join(); +} + +void +debounce_test_client::on_availability( + vsomeip::service_t _service, vsomeip::instance_t _instance, + bool _is_available) { + + if (_service == DEBOUNCE_SERVICE + && _instance == DEBOUNCE_INSTANCE) { + + if (_is_available) { + VSOMEIP_ERROR << __func__ << ": Debounce service becomes available."; + { + std::lock_guard its_lock(run_mutex_); + is_available_ = true; + } + run_condition_.notify_one(); + } else { + VSOMEIP_ERROR << __func__ << ": Debounce service becomes unavailable."; + is_available_ = false; + } + } +} + +void +debounce_test_client::on_message( + const std::shared_ptr &_message) { + + std::stringstream s; + s << "RECV: "; + for (uint32_t i = 0; i < _message->get_payload()->get_length(); i++) + s << std::hex << std::setw(2) << std::setfill('0') + << (int)_message->get_payload()->get_data()[i] << " "; + VSOMEIP_DEBUG << s.str(); + + if (DEBOUNCE_SERVICE == _message->get_service() + && DEBOUNCE_EVENT == _message->get_method()) { + + if (test_id_ == debounce_test_id_e::DTI_FLAT) { + bool is_equal = compare_payload(_message->get_payload(), index_++); + EXPECT_EQ(is_equal, true); + if (!is_equal || index_ == 5) + run_condition_.notify_one(); + } + + return; + } + + if (DEBOUNCE_SERVICE == _message->get_service() + && DEBOUNCE_EVENT_2 == _message->get_method()) { + + if (test_id_ == debounce_test_id_e::DTI_INCREASE + || test_id_ == debounce_test_id_e::DTI_DECREASE) { + bool is_equal = compare_payload(_message->get_payload(), index_++); + EXPECT_EQ(is_equal, true); + + if (!is_equal || index_ == 6) + run_condition_.notify_one(); + } + + return; + } + + if (DEBOUNCE_SERVICE == _message->get_service() + && DEBOUNCE_EVENT_4 == _message->get_method()) { + + if (test_id_ == debounce_test_id_e::DTI_MASK) { + bool is_equal = compare_payload(_message->get_payload(), index_++); + EXPECT_EQ(is_equal, true); + + if (!is_equal || index_ == 6) + run_condition_.notify_one(); + } + + return; + } +} + +bool +debounce_test_client::compare_payload( + const std::shared_ptr &_payload, + std::size_t _index) const { + + auto its_expected_payload = payloads__[test_id_][_index]; + return ((*_payload) == (*its_expected_payload)); +} + +void +debounce_test_client::run_test() { + + // Trigger the test + auto its_runtime = vsomeip::runtime::get(); + auto its_payload = its_runtime->create_payload(); + auto its_message = its_runtime->create_request(false); + its_message->set_service(DEBOUNCE_SERVICE); + its_message->set_instance(DEBOUNCE_INSTANCE); + its_message->set_method(DEBOUNCE_START_METHOD); + its_message->set_interface_version(DEBOUNCE_MAJOR); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + its_message->set_payload(its_payload); + app_->send(its_message); + + // Wait for the result + std::unique_lock its_lock(run_mutex_); + if (!is_available_) { + auto its_result = run_condition_.wait_for( + its_lock, std::chrono::milliseconds(5000)); + + EXPECT_EQ(its_result, std::cv_status::no_timeout); + } + + std::this_thread::sleep_for(std::chrono::seconds(2)); +} + +void +debounce_test_client::unsubscribe_all() { + + app_->unsubscribe(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENTGROUP); +} + +void +debounce_test_client::stop_service() { + + auto its_runtime = vsomeip::runtime::get(); + auto its_payload = its_runtime->create_payload(); + auto its_message = its_runtime->create_request(false); + its_message->set_service(DEBOUNCE_SERVICE); + its_message->set_instance(DEBOUNCE_INSTANCE); + its_message->set_method(DEBOUNCE_STOP_METHOD); + its_message->set_interface_version(DEBOUNCE_MAJOR); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + its_message->set_payload(its_payload); + app_->send(its_message); +} + + +TEST(debounce_test, flat) { + debounce_test_client its_client(debounce_test_id_e::DTI_FLAT); + if (its_client.init()) { + VSOMEIP_ERROR << "debounce_client successfully initialized!"; + its_client.start(); + its_client.wait(); + } else { + VSOMEIP_ERROR << "debounce_client could not be initialized!"; + } +} + +TEST(debounce_test, increase) { + debounce_test_client its_client(debounce_test_id_e::DTI_INCREASE); + if (its_client.init()) { + VSOMEIP_ERROR << "debounce_client successfully initialized!"; + its_client.start(); + its_client.wait(); + } else { + VSOMEIP_ERROR << "debounce_client could not be initialized!"; + } +} + +TEST(debounce_test, decrease) { + debounce_test_client its_client(debounce_test_id_e::DTI_DECREASE); + if (its_client.init()) { + VSOMEIP_ERROR << "debounce_client successfully initialized!"; + its_client.start(); + its_client.wait(); + } else { + VSOMEIP_ERROR << "debounce_client could not be initialized!"; + } +} + +TEST(debounce_test, mask) { + debounce_test_client its_client(debounce_test_id_e::DTI_MASK); + if (its_client.init()) { + VSOMEIP_ERROR << "debounce_client successfully initialized!"; + its_client.start(); + its_client.wait(); + } else { + VSOMEIP_ERROR << "debounce_client could not be initialized!"; + } +} + +int main(int argc, char** argv) { + + std::shared_ptr its_payload; + + // Flat test + payloads__.push_back(std::vector >()); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_FLAT].push_back(its_payload); + + // Increase test + payloads__.push_back(std::vector >()); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08 }); + payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09 }); + payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09, 0x0A }); + payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C }); + payloads__[debounce_test_id_e::DTI_INCREASE].push_back(its_payload); + + // Decrease test + payloads__.push_back(std::vector >()); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C }); + payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09, 0x0A }); + payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09 }); + payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08 }); + payloads__[debounce_test_id_e::DTI_DECREASE].push_back(its_payload); + + // Mask test + payloads__.push_back(std::vector >()); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x10, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x20, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x22, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x23, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); + + its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data({ 0x24, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + payloads__[debounce_test_id_e::DTI_MASK].push_back(its_payload); + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/debounce_tests/debounce_test_client.hpp b/test/network_tests/debounce_tests/debounce_test_client.hpp new file mode 100644 index 0000000..0480ea3 --- /dev/null +++ b/test/network_tests/debounce_tests/debounce_test_client.hpp @@ -0,0 +1,56 @@ +// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef DEBOUNCE_TEST_CLIENT_HPP_ +#define DEBOUNCE_TEST_CLIENT_HPP_ + +#include +#include +#include + +#include + +#include + +#include "debounce_test_common.hpp" + +class debounce_test_client { +public: + debounce_test_client(debounce_test_id_e _test_id); + + bool init(); + void start(); + void stop(); + + void run(); + void wait(); + +private: + void on_availability( + vsomeip::service_t _service, vsomeip::instance_t _instance, + bool _is_available); + void on_message(const std::shared_ptr &_message); + + void run_test(); + void unsubscribe_all(); + void stop_service(); + + bool compare_payload(const std::shared_ptr &_payload, + std::size_t _index) const; + +private: + debounce_test_id_e test_id_; + size_t index_; + + bool is_available_; + + std::mutex run_mutex_; + std::condition_variable run_condition_; + + std::thread runner_; + std::shared_ptr app_; +}; + +#endif // DEBOUNCE_TEST_CLIENT_HPP_ diff --git a/test/network_tests/debounce_tests/debounce_test_common.hpp b/test/network_tests/debounce_tests/debounce_test_common.hpp new file mode 100644 index 0000000..b4c5df6 --- /dev/null +++ b/test/network_tests/debounce_tests/debounce_test_common.hpp @@ -0,0 +1,29 @@ +// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef DEBOUNCE_TEST_COMMON_HPP_ +#define DEBOUNCE_TEST_COMMON_HPP_ + +#include + +const vsomeip::service_t DEBOUNCE_SERVICE = 0xb657; +const vsomeip::instance_t DEBOUNCE_INSTANCE = 0x0003; +const vsomeip::method_t DEBOUNCE_START_METHOD = 0x0998; +const vsomeip::method_t DEBOUNCE_STOP_METHOD = 0x0999; +const vsomeip::event_t DEBOUNCE_EVENT = 0x8001; +const vsomeip::event_t DEBOUNCE_EVENT_2 = 0x8002; +const vsomeip::event_t DEBOUNCE_EVENT_4 = 0x8004; +const vsomeip::eventgroup_t DEBOUNCE_EVENTGROUP = 0x0005; +const vsomeip::major_version_t DEBOUNCE_MAJOR = 0x01; +const vsomeip::minor_version_t DEBOUNCE_MINOR = 0x01; + +enum debounce_test_id_e : uint8_t { + DTI_FLAT = 0x00, + DTI_INCREASE = 0x01, + DTI_DECREASE = 0x02, + DTI_MASK = 0x03 +}; + +#endif // DEBOUNCE_TEST_COMMON_HPP_ diff --git a/test/network_tests/debounce_tests/debounce_test_master_starter.sh b/test/network_tests/debounce_tests/debounce_test_master_starter.sh new file mode 100755 index 0000000..534c2ff --- /dev/null +++ b/test/network_tests/debounce_tests/debounce_test_master_starter.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 + +export VSOMEIP_CONFIGURATION=debounce_test_client.json +../../examples/routingmanagerd/routingmanagerd & +PID_VSOMEIPD=$! + +sleep 1 + +./debounce_test_client & +PID_MASTER=$! + +sleep 1 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting debounce test on slave LXC debounce_test_slave_starter.sh" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./debounce_test_slave_starter.sh\"" & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS; sleep 10; ./debounce_test_slave_starter.sh" & +else +cat < + +#include "debounce_test_service.hpp" + +debounce_test_service::debounce_test_service(debounce_test_id_e _test_id) + : test_id_(_test_id), + is_running_(true), + runner_(std::bind(&debounce_test_service::run, this)), + app_(vsomeip::runtime::get()->create_application("debounce_test_service")) { + +} + +bool +debounce_test_service::init() { + + bool is_initialized = app_->init(); + if (is_initialized) { + app_->register_message_handler( + DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_START_METHOD, + std::bind(&debounce_test_service::on_start, this, + std::placeholders::_1)); + app_->register_message_handler( + DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_STOP_METHOD, + std::bind(&debounce_test_service::on_stop, this, + std::placeholders::_1)); + app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENT, { DEBOUNCE_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), + false, true, nullptr, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENT_2, { DEBOUNCE_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), + false, true, nullptr, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->offer_event(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_EVENT_4, { DEBOUNCE_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), + false, true, nullptr, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->offer_service(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, + DEBOUNCE_MAJOR, DEBOUNCE_MINOR); + } + return (is_initialized); +} + +void +debounce_test_service::start() { + + app_->start(); +} + +void +debounce_test_service::stop() { + + app_->stop(); +} + +void +debounce_test_service::run() { + + { + std::unique_lock its_lock(run_mutex_); + auto its_result = run_condition_.wait_for( + its_lock, std::chrono::milliseconds(5000)); + if (its_result == std::cv_status::timeout) + return; + } + + start_test(); +} + +void +debounce_test_service::wait() { + + if (runner_.joinable()) + runner_.join(); +} + +void +debounce_test_service::on_start( + const std::shared_ptr &_message) { + + (void)_message; + + VSOMEIP_INFO << __func__ << ": Starting test " << std::dec << test_id_; + run_condition_.notify_one(); +} + + +void +debounce_test_service::on_stop( + const std::shared_ptr &_message) { + + (void)_message; + + VSOMEIP_INFO << __func__ << ": Received a STOP command."; + is_running_ = false; + stop(); +} + +void +debounce_test_service::start_test() { + + if (test_id_ == debounce_test_id_e::DTI_FLAT) { + auto its_payload = vsomeip::runtime::get()->create_payload(); + + its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x03, 0x02, 0x03, 0x04, 0x04, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x05, 0x02, 0x03, 0x04, 0x03, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x07, 0x02, 0x03, 0x04, 0x02, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + + its_payload->set_data({ 0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT, its_payload); + } + + if (test_id_ == debounce_test_id_e::DTI_INCREASE) { + auto its_payload = vsomeip::runtime::get()->create_payload(); + + its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07, 0x08 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x03, 0x02, 0x03, 0x04, 0x04, 0x07, 0x07, 0x08, 0x09 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x05, 0x02, 0x03, 0x04, 0x03, 0x07, 0x07, 0x08, 0x09, 0x0A }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09, 0x0A }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x07, 0x02, 0x03, 0x04, 0x02, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + } + + if (test_id_ == debounce_test_id_e::DTI_DECREASE) { + auto its_payload = vsomeip::runtime::get()->create_payload(); + + its_payload->set_data({ 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x04, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x03, 0x02, 0x03, 0x04, 0x04, 0x07, 0x07, 0x08, 0x09, 0x0A }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x04, 0x02, 0x03, 0x04, 0x03, 0x06, 0x07, 0x08, 0x09, 0x0A }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x05, 0x02, 0x03, 0x04, 0x03, 0x07, 0x07, 0x08, 0x09 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x06, 0x02, 0x03, 0x04, 0x02, 0x06, 0x07, 0x08, 0x09 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x07, 0x02, 0x03, 0x04, 0x02, 0x07, 0x07, 0x08 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x08, 0x02, 0x03, 0x04, 0x01, 0x06, 0x07, 0x08 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + + its_payload->set_data({ 0x09, 0x02, 0x03, 0x04, 0x01, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_2, its_payload); + } + + if (test_id_ == debounce_test_id_e::DTI_MASK) { + auto its_payload = vsomeip::runtime::get()->create_payload(); + + its_payload->set_data({ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x10, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x12, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x20, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x21, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x22, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x23, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x24, 0x02, 0x03, 0x04, 0x05, 0x07, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + + its_payload->set_data({ 0x25, 0x02, 0x03, 0x04, 0x05, 0x17, 0x07 }); + app_->notify(DEBOUNCE_SERVICE, DEBOUNCE_INSTANCE, DEBOUNCE_EVENT_4, its_payload); + } +} + +TEST(debounce_test, flat) { + debounce_test_service its_service(debounce_test_id_e::DTI_FLAT); + if (its_service.init()) { + its_service.start(); + its_service.wait(); + } +} + +TEST(debounce_test, increase) { + debounce_test_service its_service(debounce_test_id_e::DTI_INCREASE); + if (its_service.init()) { + its_service.start(); + its_service.wait(); + } +} + +TEST(debounce_test, decrease) { + debounce_test_service its_service(debounce_test_id_e::DTI_DECREASE); + if (its_service.init()) { + its_service.start(); + its_service.wait(); + } +} + +TEST(debounce_test, mask) { + debounce_test_service its_service(debounce_test_id_e::DTI_MASK); + if (its_service.init()) { + its_service.start(); + its_service.wait(); + } +} + +int main(int argc, char** argv) { + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/debounce_tests/debounce_test_service.hpp b/test/network_tests/debounce_tests/debounce_test_service.hpp new file mode 100644 index 0000000..0271ae1 --- /dev/null +++ b/test/network_tests/debounce_tests/debounce_test_service.hpp @@ -0,0 +1,48 @@ +// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef DEBOUNCE_TEST_SERVICE_HPP_ +#define DEBOUNCE_TEST_SERVICE_HPP_ + +#include +#include +#include +#include + +#include + +#include + +#include "debounce_test_common.hpp" + +class debounce_test_service { +public: + debounce_test_service(debounce_test_id_e _test_id); + + bool init(); + void start(); + void stop(); + + void run(); + void wait(); + +private: + void on_start(const std::shared_ptr &_message); + void on_stop(const std::shared_ptr &_message); + + void start_test(); + + debounce_test_id_e test_id_; + + std::mutex run_mutex_; + std::condition_variable run_condition_; + + std::atomic is_running_; + std::thread runner_; + std::shared_ptr app_; +}; + + +#endif // DEBOUNCE_TEST_SERVICE_HPP_ diff --git a/test/network_tests/debounce_tests/debounce_test_slave_starter.sh b/test/network_tests/debounce_tests/debounce_test_slave_starter.sh new file mode 100755 index 0000000..ce5b230 --- /dev/null +++ b/test/network_tests/debounce_tests/debounce_test_slave_starter.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 + +export VSOMEIP_CONFIGURATION=debounce_test_service.json +../../examples/routingmanagerd/routingmanagerd & +PID_VSOMEIPD=$! + +sleep 1 + +./debounce_test_service & +PID_SLAVE=$! + +# Wait until all slaves are finished +for job in $PID_SLAVE +do + # Fail gets incremented if a client exits with a non-zero exit code + echo "waiting for $job" + wait $job || FAIL=$(($FAIL+1)) +done + +# kill the services +kill $PID_VSOMEIPD +sleep 3 + +# Check if everything went well +exit $FAIL diff --git a/test/network_tests/e2e_tests/conf/e2e_profile_04_test_client_external.json.in b/test/network_tests/e2e_tests/conf/e2e_profile_04_test_client_external.json.in new file mode 100644 index 0000000..6952459 --- /dev/null +++ b/test/network_tests/e2e_tests/conf/e2e_profile_04_test_client_external.json.in @@ -0,0 +1,56 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "info", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "client-sample", + "id" : "0x1255" + } + ], + "e2e" : + { + "e2e_enabled" : "true", + "protected" : + [ + { + "service_id" : "0xd025", + "event_id" : "0x0001", + "profile" : "P04", + "variant" : "checker", + "crc_offset" : "64", + "data_id" : "0x2d" + }, + { + "service_id" : "0xd025", + "event_id" : "0x8001", + "profile" : "P04", + "variant" : "checker", + "crc_offset" : "64", + "data_id" : "0x2d" + } + ] + }, + "routing" : "client-sample", + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "100", + "repetitions_base_delay" : "200", + "repetitions_max" : "3", + "ttl" : "3", + "cyclic_offer_delay" : "1000", + "request_response_delay" : "1500" + } +} diff --git a/test/network_tests/e2e_tests/conf/e2e_profile_04_test_service_external.json.in b/test/network_tests/e2e_tests/conf/e2e_profile_04_test_service_external.json.in new file mode 100644 index 0000000..efeffef --- /dev/null +++ b/test/network_tests/e2e_tests/conf/e2e_profile_04_test_service_external.json.in @@ -0,0 +1,57 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "info", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "service-sample", + "id" : "0x1277", + "has_session_handling" : "false" + } + ], + "services" : + [ + { + "service" : "0xd025", + "instance" : "0x0001", + "unreliable" : "30501" + } + ], + "e2e" : + { + "e2e_enabled" : "true", + "protected" : + [ + { + "service_id" : "0xd025", + "event_id" : "0x0001", + "profile" : "P04", + "variant" : "protector", + "crc_offset" : "64", + "data_id" : "0x2d" + } + ] + }, + "routing" : "service-sample", + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "100", + "repetitions_base_delay" : "200", + "repetitions_max" : "3", + "ttl" : "3", + "cyclic_offer_delay" : "2000", + "request_response_delay" : "1500" + } +} diff --git a/test/network_tests/e2e_tests/conf/e2e_test_client_external.json.in b/test/network_tests/e2e_tests/conf/e2e_test_client_external.json.in new file mode 100644 index 0000000..d00c4bf --- /dev/null +++ b/test/network_tests/e2e_tests/conf/e2e_test_client_external.json.in @@ -0,0 +1,83 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "info", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "client-sample", + "id" : "0x1255" + } + ], + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + } + ], + "e2e" : + { + "e2e_enabled" : "true", + "protected" : + [ + { + "service_id" : "0x1234", + "event_id" : "0x8421", + "profile" : "CRC8", + "variant" : "checker", + "crc_offset" : "0", + "data_id_mode" : "3", + "data_length" : "56", + "data_id" : "0xA73" + }, + { + "service_id" : "0x1234", + "event_id" : "0x8001", + "profile" : "CRC8", + "variant" : "checker", + "crc_offset" : "0", + "data_id_mode" : "3", + "data_length" : "56", + "data_id" : "0xA73" + }, + { + "service_id" : "0x1234", + "event_id" : "0x6543", + "profile" : "CRC32", + "variant" : "checker", + "crc_offset" : "0" + }, + { + "service_id" : "0x1234", + "event_id" : "0x8002", + "profile" : "CRC32", + "variant" : "checker", + "crc_offset" : "0" + } + ] + }, + "routing" : "client-sample", + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "100", + "repetitions_base_delay" : "200", + "repetitions_max" : "3", + "ttl" : "3", + "cyclic_offer_delay" : "2000", + "request_response_delay" : "1500" + } +} diff --git a/test/network_tests/e2e_tests/conf/e2e_test_service_external.json.in b/test/network_tests/e2e_tests/conf/e2e_test_service_external.json.in new file mode 100644 index 0000000..d2b8e04 --- /dev/null +++ b/test/network_tests/e2e_tests/conf/e2e_test_service_external.json.in @@ -0,0 +1,66 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "info", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "service-sample", + "id" : "0x1277" + } + ], + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + } + ], + "e2e" : + { + "e2e_enabled" : "true", + "protected" : + [ + { + "service_id" : "0x1234", + "event_id" : "0x8001", + "profile" : "CRC8", + "variant" : "protector", + "crc_offset" : "0", + "data_id_mode" : "3", + "data_length" : "56", + "data_id" : "0xA73" + }, + { + "service_id" : "0x1234", + "event_id" : "0x8002", + "profile" : "CRC32", + "variant" : "protector", + "crc_offset" : "0" + } + ] + }, + "routing" : "service-sample", + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "100", + "repetitions_base_delay" : "200", + "repetitions_max" : "3", + "ttl" : "3", + "cyclic_offer_delay" : "2000", + "request_response_delay" : "1500" + } +} diff --git a/test/network_tests/e2e_tests/e2e_profile_04_test_client.cpp b/test/network_tests/e2e_tests/e2e_profile_04_test_client.cpp new file mode 100644 index 0000000..23c9c06 --- /dev/null +++ b/test/network_tests/e2e_tests/e2e_profile_04_test_client.cpp @@ -0,0 +1,313 @@ +// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "e2e_profile_04_test_common.hpp" +#include "e2e_profile_04_test_client.hpp" + +#include + +std::vector> responses_; +std::vector> events_; + +std::map counters_; + + +e2e_profile_04_test_client::e2e_profile_04_test_client() + : app_(vsomeip::runtime::get()->create_application()), + is_available_(false), + sender_(std::bind(&e2e_profile_04_test_client::run, this)), + received_(0) { + +} + +bool +e2e_profile_04_test_client::init() { + + if (!app_->init()) { + ADD_FAILURE() << __func__ << ": Cannot initialize application"; + return (false); + } + + app_->register_state_handler( + std::bind(&e2e_profile_04_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler( + PROFILE_04_SERVICE, PROFILE_04_INSTANCE, vsomeip::ANY_METHOD, + std::bind(&e2e_profile_04_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler( + PROFILE_04_SERVICE, PROFILE_04_INSTANCE, + std::bind(&e2e_profile_04_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + return (true); +} + +void +e2e_profile_04_test_client::start() { + + VSOMEIP_INFO << __func__ << ": Starting..."; + app_->start(); +} + +void +e2e_profile_04_test_client::stop() { + + VSOMEIP_INFO << __func__ << ": Stopping..."; + shutdown_service(); + app_->clear_all_handler(); + app_->stop(); +} + +void +e2e_profile_04_test_client::on_state(vsomeip::state_type_e _state) { + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + app_->request_service(PROFILE_04_SERVICE, PROFILE_04_INSTANCE); + + // request event 0x8001, that is protected by E2E Profile 04 + app_->request_event(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, + PROFILE_04_EVENT, { PROFILE_04_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + } +} + +void +e2e_profile_04_test_client::on_availability( + vsomeip::service_t _service, vsomeip::instance_t _instance, + bool _is_available) { + + VSOMEIP_INFO << __func__ << ": Client " + << std::hex << std::setw(4) << std::setfill('0') + << app_->get_client() + << " : Service [" << _service << "." << _instance + << "] is " << (_is_available ? "available." : "NOT available."); + + // check that correct service / instance ID gets available + if (_is_available) { + EXPECT_EQ(PROFILE_04_SERVICE, _service); + EXPECT_EQ(PROFILE_04_INSTANCE, _instance); + } + + if (PROFILE_04_SERVICE == _service && PROFILE_04_INSTANCE == _instance) { + std::unique_lock its_lock(mutex_); + if (is_available_ && !_is_available) { + is_available_ = false; + } else if(_is_available && !is_available_) { + is_available_ = true; + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + app_->subscribe(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, + PROFILE_04_EVENTGROUP, PROFILE_04_MAJOR); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + condition_.notify_one(); + } + } +} + +void +e2e_profile_04_test_client::on_message(const std::shared_ptr &_message) { + + VSOMEIP_INFO << __func__ << ": Received a message from Service [" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_service() << "." << _message->get_instance() + << "] to Client/Session [" + << _message->get_client() << "/" << _message->get_session() + << "]"; + + EXPECT_EQ(PROFILE_04_SERVICE, _message->get_service()); + EXPECT_EQ(PROFILE_04_INSTANCE, _message->get_instance()); + + // check fixed payload / CRC in response for service: d025 method: 0001 + if (vsomeip::message_type_e::MT_RESPONSE == _message->get_message_type() + && PROFILE_04_METHOD == _message->get_method()) { + // check for calculated CRC status OK for the predefined fixed payload sent by service + VSOMEIP_INFO << "Method ID 0x0001 -> IS_VALID_CRC = " + << std::boolalpha << _message->is_valid_crc(); + EXPECT_EQ(true, _message->is_valid_crc()); + + // check if payload is as expected as well (including CRC / counter / data ID) + std::shared_ptr its_payload = _message->get_payload(); + const auto its_data = its_payload->get_data(); + for (size_t i = 0; i < its_payload->get_length(); i++) + EXPECT_EQ(its_data[i], responses_[counters_[PROFILE_04_METHOD] + % PROFILE_O4_NUM_MESSAGES][i]); + + counters_[PROFILE_04_METHOD]++; + + } else if (vsomeip::message_type_e::MT_NOTIFICATION == _message->get_message_type() + && PROFILE_04_EVENT == _message->get_method()) { + + // check CRC / payload calculated by sender for event 0x8001 against expected payload + // check for calculated CRC status OK for the calculated CRC / payload sent by service + VSOMEIP_INFO << __func__ << ": Event 0x8001 -> IS_VALID_CRC = " + << std::boolalpha << _message->is_valid_crc(); + EXPECT_EQ(true, _message->is_valid_crc()); + + // check if payload is as expected as well (including CRC / counter / data ID nibble) + std::shared_ptr its_payload = _message->get_payload(); + const auto its_data = its_payload->get_data(); + for (size_t i = 0; i< its_payload->get_length(); i++) + EXPECT_EQ(its_data[i], events_[counters_[PROFILE_04_EVENT] + % PROFILE_O4_NUM_MESSAGES][i]); + + counters_[PROFILE_04_EVENT]++; + } + + received_++; + if (received_ == PROFILE_O4_NUM_MESSAGES * 2) { + VSOMEIP_WARNING << __func__ << ": Client" + << std::setw(4) << std::setfill('0') << std::hex + << app_->get_client() + << " received all messages ~> going down!"; + } +} + +void +e2e_profile_04_test_client::run() { + + for (int i = 0; i < PROFILE_O4_NUM_MESSAGES; ++i) { + { + std::unique_lock its_lock(mutex_); + while (!is_available_) { + condition_.wait(its_lock); + } + } + + auto request = vsomeip::runtime::get()->create_request(false); + request->set_service(PROFILE_04_SERVICE); + request->set_instance(PROFILE_04_INSTANCE); + request->set_interface_version(PROFILE_04_MAJOR); + + // send a request which is not e2e protected and expect an + // protected answer holding a fixed payload (E2E Profile 04) + // this call triggers also an event 0x8001 which holds a + // calculated payload + request->set_method(PROFILE_04_METHOD); + + app_->send(request); + + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + } + + stop(); +} + +void +e2e_profile_04_test_client::join_sender_thread() { + + if (sender_.joinable()) { + sender_.join(); + } +} + +void +e2e_profile_04_test_client::shutdown_service() { + + auto request = vsomeip::runtime::get()->create_request(false); + request->set_service(PROFILE_04_SERVICE); + request->set_instance(PROFILE_04_INSTANCE); + request->set_method(PROFILE_04_SHUTDOWN); + request->set_interface_version(PROFILE_04_MAJOR); + + app_->send(request); + + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + + // expect 10 responses + 10 events + EXPECT_EQ(received_, PROFILE_O4_NUM_MESSAGES * 2); +} + +TEST(someip_e2e_profile_04_test, test_crc_calculation) { + + e2e_profile_04_test_client test_client; + + if (test_client.init()) { + test_client.start(); + test_client.join_sender_thread(); + } +} + +int main(int argc, char** argv) { + + responses_ = { + { + 0x00, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00, 0x2d, + 0xaa, 0x1d, 0x3f, 0xdf, 0x08, 0xb7, 0xf4, 0x4c, + 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, + 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, + 0x3d, 0x83, 0x3e, 0xba, 0x68, 0xed, 0x3f, 0xb3, + 0x7a, 0xf2, 0xbd, 0x96, 0xc1, 0x42, 0x3d, 0x25, + 0x1a, 0x62, 0xbd, 0xae, 0x77, 0xf3, 0x3f, 0x80, + 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1d, 0xbd, + 0x4e, 0x01, 0x01, 0x3c, 0x2b, 0x87, 0xed, 0x00 + }, + { + 0x00, 0x50, 0x00, 0x01, 0x01, 0x00, 0x00, 0x2d, + 0xe7, 0xb7, 0x13, 0x87, 0x0c, 0x69, 0x02, 0x1c, + 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, + 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, + 0x3c, 0x2f, 0x3e, 0xba, 0x46, 0x81, 0x3f, 0xb3, + 0x73, 0x8d, 0xbd, 0x93, 0xcb, 0xae, 0x3c, 0xf7, + 0xd2, 0x58, 0xbd, 0xa2, 0x6e, 0xcd, 0x3f, 0x80, + 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x89, + 0x24, 0x01, 0x01, 0x3c, 0x2b, 0x24, 0x45, 0x00 + }, + { + 0x00, 0x50, 0x00, 0x02, 0x01, 0x00, 0x00, 0x2d, + 0xb6, 0x19, 0x94, 0x2c, 0x10, 0x1b, 0x28, 0xae, + 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, + 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, + 0x3e, 0xf3, 0x3e, 0xba, 0x97, 0x45, 0x3f, 0xb3, + 0x86, 0x81, 0xbd, 0x8a, 0xda, 0xc2, 0x3c, 0xf6, + 0x00, 0x7a, 0xbd, 0xb4, 0xf9, 0xb9, 0x3f, 0x80, + 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x1b, + 0x72, 0x01, 0x01, 0x3c, 0x2a, 0x9e, 0x1f, 0x00 + } + }; + + events_ = { + { + 0x00, 0x50, 0x8f, 0x81, 0x01, 0x00, 0x00, 0x2d, + 0xed, 0x6e, 0x78, 0x8d, 0x08, 0xb7, 0xf4, 0x4c, + 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, + 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, + 0x3d, 0x83, 0x3e, 0xba, 0x68, 0xed, 0x3f, 0xb3, + 0x7a, 0xf2, 0xbd, 0x96, 0xc1, 0x42, 0x3d, 0x25, + 0x1a, 0x62, 0xbd, 0xae, 0x77, 0xf3, 0x3f, 0x80, + 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1d, 0xbd, + 0x4e, 0x01, 0x01, 0x3c, 0x2b, 0x87, 0xed, 0x00 + }, + { + 0x00, 0x50, 0x8f, 0x82, 0x01, 0x00, 0x00, 0x2d, + 0x9d, 0xbb, 0x49, 0x3f, 0x0c, 0x69, 0x02, 0x1c, + 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, + 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, + 0x3c, 0x2f, 0x3e, 0xba, 0x46, 0x81, 0x3f, 0xb3, + 0x73, 0x8d, 0xbd, 0x93, 0xcb, 0xae, 0x3c, 0xf7, + 0xd2, 0x58, 0xbd, 0xa2, 0x6e, 0xcd, 0x3f, 0x80, + 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x89, + 0x24, 0x01, 0x01, 0x3c, 0x2b, 0x24, 0x45, 0x00 + }, + { + 0x00, 0x50, 0x8f, 0x83, 0x01, 0x00, 0x00, 0x2d, + 0x13, 0x04, 0xf8, 0x81, 0x10, 0x1b, 0x28, 0xae, + 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, + 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, + 0x3e, 0xf3, 0x3e, 0xba, 0x97, 0x45, 0x3f, 0xb3, + 0x86, 0x81, 0xbd, 0x8a, 0xda, 0xc2, 0x3c, 0xf6, + 0x00, 0x7a, 0xbd, 0xb4, 0xf9, 0xb9, 0x3f, 0x80, + 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x1b, + 0x72, 0x01, 0x01, 0x3c, 0x2a, 0x9e, 0x1f, 0x00 + } + }; + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/e2e_tests/e2e_profile_04_test_client.hpp b/test/network_tests/e2e_tests/e2e_profile_04_test_client.hpp new file mode 100644 index 0000000..ad00291 --- /dev/null +++ b/test/network_tests/e2e_tests/e2e_profile_04_test_client.hpp @@ -0,0 +1,48 @@ +// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef E2E_PROFILE_04_TEST_CLIENT_HPP_ +#define E2E_PROFILE_04_TEST_CLIENT_HPP_ + +#include + +#include + +#include +#include +#include +#include + +class e2e_profile_04_test_client { +public: + e2e_profile_04_test_client(); + + bool init(); + void start(); + void stop(); + + void on_state(vsomeip::state_type_e _state); + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available); + void on_message(const std::shared_ptr &_response); + + void run(); + void join_sender_thread(); + +private: + void shutdown_service(); + + std::shared_ptr app_; + + std::mutex mutex_; + std::condition_variable condition_; + bool is_available_; + + std::thread sender_; + + std::atomic received_; +}; + +#endif // E2E_PROFILE_04_TEST_CLIENT_HPP_ diff --git a/test/network_tests/e2e_tests/e2e_profile_04_test_common.hpp b/test/network_tests/e2e_tests/e2e_profile_04_test_common.hpp new file mode 100644 index 0000000..04cba23 --- /dev/null +++ b/test/network_tests/e2e_tests/e2e_profile_04_test_common.hpp @@ -0,0 +1,24 @@ +// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef E2E_PROFILE_04_TEST_COMMON_HPP_ +#define E2E_PROFILE_04_TEST_COMMON_HPP_ + +#include + +const vsomeip::service_t PROFILE_04_SERVICE = 0xd025; +const vsomeip::instance_t PROFILE_04_INSTANCE = 0x0001; +const vsomeip::major_version_t PROFILE_04_MAJOR = 0x01; +const vsomeip::minor_version_t PROFILE_04_MINOR = 0x00000000; + +const vsomeip::method_t PROFILE_04_METHOD = 0x0001; +const vsomeip::method_t PROFILE_04_SHUTDOWN = 0x0002; + +const vsomeip::eventgroup_t PROFILE_04_EVENTGROUP = 0x0001; +const vsomeip::event_t PROFILE_04_EVENT = 0x8001; + +#define PROFILE_O4_NUM_MESSAGES 3 + +#endif // E2E_PROFILE_04_TEST_COMMON_HPP_ diff --git a/test/network_tests/e2e_tests/e2e_profile_04_test_external_master_start.sh b/test/network_tests/e2e_tests/e2e_profile_04_test_external_master_start.sh new file mode 100755 index 0000000..df2095b --- /dev/null +++ b/test/network_tests/e2e_tests/e2e_profile_04_test_external_master_start.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# Copyright (C) 2015-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +if [ $# -lt 1 ] +then + echo "Please pass a json file to this script" + echo "For example: $0 e2e_profile_04_test_client_external.json" + exit 1 +fi + +MASTER_JSON_FILE=$1 +SERVICE_JSON_FILE=${MASTER_JSON_FILE/client/service} +ALLOW_DENY=$2 + +FAIL=0 + +export VSOMEIP_CONFIGURATION=$1 +export VSOMEIP_APPLICATION_NAME=client-sample +./e2e_profile_04_test_client --remote & +PID_CLIENT=$! + + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting external e2e profile 04 test on slave LXC" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./e2e_profile_04_test_external_slave_start.sh $SERVICE_JSON_FILE\"" & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./e2e_profile_04_test_external_slave_start.sh $SERVICE_JSON_FILE" & +else +cat < > responses_; +std::vector > events_; + +std::map counters_; + +e2e_profile_04_test_service::e2e_profile_04_test_service() + : app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + blocked_(false), + offer_thread_(std::bind(&e2e_profile_04_test_service::run, this)), + received_(0) { +} + +bool +e2e_profile_04_test_service::init() { + + std::lock_guard its_lock(mutex_); + + if (!app_->init()) { + ADD_FAILURE() << __func__ << ": Cannot initialize application."; + return false; + } + + app_->register_message_handler(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, + PROFILE_04_METHOD, + std::bind(&e2e_profile_04_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, + PROFILE_04_SHUTDOWN, + std::bind(&e2e_profile_04_test_service::on_message_shutdown, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&e2e_profile_04_test_service::on_state, this, + std::placeholders::_1)); + + // E2E Profile 04: Event 8001 + app_->offer_event(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, + PROFILE_04_EVENT, { PROFILE_04_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + + // Initialize the attribute + auto its_payload = vsomeip::runtime::get()->create_payload(); + vsomeip::byte_t its_data[] = { + 0x00, 0x50, 0x8f, 0x80, 0x01, 0x00, 0x00, 0x2d, + 0xf3, 0x2a, 0x8c, 0x89, 0x05, 0x04, 0xcc, 0x46, + 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, + 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, + 0x40, 0xb1, 0x3e, 0xba, 0xc4, 0x76, 0x3f, 0xb3, + 0x7b, 0x03, 0xbd, 0x95, 0x74, 0x53, 0x3d, 0x32, + 0x4b, 0x9d, 0xbd, 0xbc, 0xd6, 0x3b, 0x3f, 0x80, + 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1f, 0xf5, + 0xf6, 0x01, 0x01, 0x3c, 0x2b, 0xb1, 0xa2, 0x00 + }; + its_payload->set_data(its_data, sizeof(its_data)); + + app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8001), its_payload); + + return (true); +} + +void +e2e_profile_04_test_service::start() { + + VSOMEIP_INFO << __func__ << ": Starting..."; + app_->start(); +} + +void +e2e_profile_04_test_service::stop() { + + VSOMEIP_INFO << __func__ << ": Stopping..."; + app_->clear_all_handler(); + app_->stop(); +} + +void +e2e_profile_04_test_service::join_offer_thread() { + + if (offer_thread_.joinable()) { + offer_thread_.join(); + } +} + +void +e2e_profile_04_test_service::offer() { + + app_->offer_service(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, + PROFILE_04_MAJOR, PROFILE_04_MINOR); +} + +void +e2e_profile_04_test_service::stop_offer() { + + app_->stop_offer_service(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, + PROFILE_04_MAJOR, PROFILE_04_MINOR); +} + +void +e2e_profile_04_test_service::on_state(vsomeip::state_type_e _state) { + + VSOMEIP_INFO << __func__ << ": Application " + << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + if (!is_registered_) { + is_registered_ = true; + + std::lock_guard its_lock(mutex_); + blocked_ = true; + + // "start" the run method thread + condition_.notify_one(); + } + } else { + is_registered_ = false; + } +} + +void +e2e_profile_04_test_service::on_message( + const std::shared_ptr &_request) { + + ASSERT_EQ(PROFILE_04_SERVICE, _request->get_service()); + ASSERT_EQ(PROFILE_04_INSTANCE, _request->get_instance()); + + VSOMEIP_INFO << "Received a message with Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex + << _request->get_client() << "/" << _request->get_session() + << "] method: " << _request->get_method() ; + + std::shared_ptr its_response = + vsomeip::runtime::get()->create_response(_request); + std::shared_ptr< vsomeip::payload > its_response_payload = + vsomeip::runtime::get()->create_payload(); + std::shared_ptr its_event_payload = + vsomeip::runtime::get()->create_payload(); + + // send fixed payload for profile 01 CRC8 + if (PROFILE_04_METHOD == _request->get_method()) { + its_response_payload->set_data(responses_[counters_[PROFILE_04_METHOD] % PROFILE_O4_NUM_MESSAGES]); + its_response->set_payload(its_response_payload); + app_->send(its_response); + + counters_[PROFILE_04_METHOD]++; + + // set value to field which gets filled by e2e protection with CRC on sending + its_event_payload->set_data(events_[counters_[PROFILE_04_EVENT] % PROFILE_O4_NUM_MESSAGES]); + app_->notify(PROFILE_04_SERVICE, PROFILE_04_INSTANCE, PROFILE_04_EVENT, its_event_payload); + + counters_[PROFILE_04_EVENT]++; + } + + received_++; + if (received_ == PROFILE_O4_NUM_MESSAGES) { + VSOMEIP_INFO << __func__ << ": Received all messages!"; + } +} + +void +e2e_profile_04_test_service::on_message_shutdown( + const std::shared_ptr &_request) { + + (void)_request; + VSOMEIP_INFO << __func__ << ": Shutdown method was called, going down now."; + stop(); +} + +void +e2e_profile_04_test_service::run() { + + std::unique_lock its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); + + offer(); +} + +TEST(someip_e2e_profile_04_test, basic_subscribe_request_response) { + e2e_profile_04_test_service test_service; + if (test_service.init()) { + test_service.start(); + test_service.join_offer_thread(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) { + + + counters_[PROFILE_04_METHOD] = 0; + counters_[PROFILE_04_EVENT] = 0; + + std::string test_remote("--remote"); + std::string test_local("--local"); + std::string test_allow_remote_client("--allow"); + std::string test_deny_remote_client("--deny"); + std::string help("--help"); + + int i = 1; + while (i < argc) + { + if(test_remote == argv[i]) + { + is_remote_test = true; + } + else if(test_local == argv[i]) + { + is_remote_test = false; + } + else if(test_allow_remote_client == argv[i]) + { + remote_client_allowed = true; + } + else if(test_deny_remote_client == argv[i]) + { + remote_client_allowed = false; + } + else if(help == argv[i]) + { + VSOMEIP_INFO << "Parameters:\n" + << "--remote: Run test between two hosts\n" + << "--local: Run test locally\n" + << "--allow: test is started with a policy that allows remote messages sent by this test client to the service\n" + << "--deny: test is started with a policy that denies remote messages sent by this test client to the service\n" + << "--help: print this help"; + } + i++; + } + + // Payloads (without counter, data id and crc) + responses_ = { + { + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0xb7, 0xf4, 0x4c, + 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, + 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, + 0x3d, 0x83, 0x3e, 0xba, 0x68, 0xed, 0x3f, 0xb3, + 0x7a, 0xf2, 0xbd, 0x96, 0xc1, 0x42, 0x3d, 0x25, + 0x1a, 0x62, 0xbd, 0xae, 0x77, 0xf3, 0x3f, 0x80, + 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1d, 0xbd, + 0x4e, 0x01, 0x01, 0x3c, 0x2b, 0x87, 0xed, 0x00 + }, + { + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x69, 0x02, 0x1c, + 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, + 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, + 0x3c, 0x2f, 0x3e, 0xba, 0x46, 0x81, 0x3f, 0xb3, + 0x73, 0x8d, 0xbd, 0x93, 0xcb, 0xae, 0x3c, 0xf7, + 0xd2, 0x58, 0xbd, 0xa2, 0x6e, 0xcd, 0x3f, 0x80, + 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x89, + 0x24, 0x01, 0x01, 0x3c, 0x2b, 0x24, 0x45, 0x00 + }, + { + 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x1b, 0x28, 0xae, + 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, + 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, + 0x3e, 0xf3, 0x3e, 0xba, 0x97, 0x45, 0x3f, 0xb3, + 0x86, 0x81, 0xbd, 0x8a, 0xda, 0xc2, 0x3c, 0xf6, + 0x00, 0x7a, 0xbd, 0xb4, 0xf9, 0xb9, 0x3f, 0x80, + 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x1b, + 0x72, 0x01, 0x01, 0x3c, 0x2a, 0x9e, 0x1f, 0x00 + } + }; + + // Payloads (full data with counter, data id and crc to be sent raw) + events_ = { + { + 0x00, 0x50, 0x8f, 0x81, 0x01, 0x00, 0x00, 0x2d, + 0xed, 0x6e, 0x78, 0x8d, 0x08, 0xb7, 0xf4, 0x4c, + 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, + 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, + 0x3d, 0x83, 0x3e, 0xba, 0x68, 0xed, 0x3f, 0xb3, + 0x7a, 0xf2, 0xbd, 0x96, 0xc1, 0x42, 0x3d, 0x25, + 0x1a, 0x62, 0xbd, 0xae, 0x77, 0xf3, 0x3f, 0x80, + 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1d, 0xbd, + 0x4e, 0x01, 0x01, 0x3c, 0x2b, 0x87, 0xed, 0x00 + }, + { + 0x00, 0x50, 0x8f, 0x82, 0x01, 0x00, 0x00, 0x2d, + 0x9d, 0xbb, 0x49, 0x3f, 0x0c, 0x69, 0x02, 0x1c, + 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, + 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, + 0x3c, 0x2f, 0x3e, 0xba, 0x46, 0x81, 0x3f, 0xb3, + 0x73, 0x8d, 0xbd, 0x93, 0xcb, 0xae, 0x3c, 0xf7, + 0xd2, 0x58, 0xbd, 0xa2, 0x6e, 0xcd, 0x3f, 0x80, + 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x89, + 0x24, 0x01, 0x01, 0x3c, 0x2b, 0x24, 0x45, 0x00 + }, + { + 0x00, 0x50, 0x8f, 0x83, 0x01, 0x00, 0x00, 0x2d, + 0x13, 0x04, 0xf8, 0x81, 0x10, 0x1b, 0x28, 0xae, + 0x00, 0x00, 0x09, 0x3d, 0x00, 0x01, 0x06, 0xfe, + 0x01, 0x3e, 0x4c, 0xcc, 0xcd, 0x80, 0x3f, 0xb2, + 0x3e, 0xf3, 0x3e, 0xba, 0x97, 0x45, 0x3f, 0xb3, + 0x86, 0x81, 0xbd, 0x8a, 0xda, 0xc2, 0x3c, 0xf6, + 0x00, 0x7a, 0xbd, 0xb4, 0xf9, 0xb9, 0x3f, 0x80, + 0x00, 0x00, 0xfc, 0x01, 0x01, 0x3c, 0x1c, 0x1b, + 0x72, 0x01, 0x01, 0x3c, 0x2a, 0x9e, 0x1f, 0x00 + } + }; + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/e2e_tests/e2e_profile_04_test_service.hpp b/test/network_tests/e2e_tests/e2e_profile_04_test_service.hpp new file mode 100644 index 0000000..626db05 --- /dev/null +++ b/test/network_tests/e2e_tests/e2e_profile_04_test_service.hpp @@ -0,0 +1,48 @@ +// Copyright (C) 2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef E2E_PROFILE_04_TEST_SERVICE_HPP_ +#define E2E_PROFILE_04_TEST_SERVICE_HPP_ + +#include + +#include + +#include "../someip_test_globals.hpp" + +#include +#include +#include +#include + +class e2e_profile_04_test_service { +public: + e2e_profile_04_test_service(); + + bool init(); + void start(); + void stop(); + void offer(); + void stop_offer(); + void join_offer_thread(); + void on_state(vsomeip::state_type_e _state); + void on_message(const std::shared_ptr &_request); + void on_message_shutdown(const std::shared_ptr &_request); + void run(); + +private: + std::shared_ptr app_; + bool is_registered_; + + bool blocked_; + std::mutex mutex_; + std::condition_variable condition_; + + std::thread offer_thread_; + + std::atomic received_; +}; + +#endif // E2E_PROFILE_04_TEST_SERVICE_HPP_ diff --git a/test/network_tests/e2e_tests/e2e_test_client.cpp b/test/network_tests/e2e_tests/e2e_test_client.cpp new file mode 100644 index 0000000..260ad7e --- /dev/null +++ b/test/network_tests/e2e_tests/e2e_test_client.cpp @@ -0,0 +1,387 @@ +// Copyright (C) 2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "e2e_test_client.hpp" + +static bool is_remote_test = false; +static bool remote_client_allowed = true; +std::vector> payloads_profile_01_; +std::vector> event_payloads_profile_01_; + +std::vector> payloads_custom_profile_; +std::vector> event_payloads_custom_profile_; + +std::map received_responses_counters_; + + +e2e_test_client::e2e_test_client(bool _test_external_communication, + bool _is_remote_client_allowed) + : app_(vsomeip::runtime::get()->create_application()), + is_available_(false), + sender_(std::bind(&e2e_test_client::run, this)), + received_responses_(0), + received_allowed_events_(0), + test_external_communication_(_test_external_communication), + is_remote_client_allowed_(_is_remote_client_allowed) { + +} + +bool e2e_test_client::init() { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + + app_->register_state_handler( + std::bind(&e2e_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, + std::bind(&e2e_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&e2e_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + return true; +} + +void e2e_test_client::start() { + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void e2e_test_client::stop() { + VSOMEIP_INFO << "Stopping..."; + shutdown_service(); + app_->clear_all_handler(); + app_->stop(); +} + +void e2e_test_client::on_state(vsomeip::state_type_e _state) { + if(_state == vsomeip::state_type_e::ST_REGISTERED) { + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); + + // request events of eventgroup 0x01 which holds events 0x8001 (CRC8) + std::set its_eventgroups; + its_eventgroups.insert(0x01); + + // request events of eventgroup 0x02 which holds events 0x8002 (CRC32) + std::set its_eventgroups_2; + its_eventgroups_2.insert(0x02); + + app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8001), + its_eventgroups, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8002), + its_eventgroups_2, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + } +} + +void e2e_test_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + + VSOMEIP_INFO << std::hex << "Client 0x" << app_->get_client() + << " : Service [" << std::setw(4) << std::setfill('0') << std::hex + << _service << "." << _instance << "] is " + << (_is_available ? "available." : "NOT available."); + + // check that correct service / instance ID gets available + if (_is_available) { + EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _service); + EXPECT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _instance); + } + + if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service + && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) { + std::unique_lock its_lock(mutex_); + if(is_available_ && !_is_available) { + is_available_ = false; + } + else if(_is_available && !is_available_) { + is_available_ = true; + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + app_->subscribe(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, 0x01); + app_->subscribe(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, 0x02); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + condition_.notify_one(); + } + } +} + +void e2e_test_client::on_message(const std::shared_ptr &_response) { + VSOMEIP_INFO << "Received a response from Service [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() + << "." + << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() + << "] to Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() + << "/" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() + << "]"; + EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _response->get_service()); + EXPECT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _response->get_instance()); + + // check fixed payload / CRC in response for service: 1234 method: 8421 + if (_response->get_message_type() == vsomeip::message_type_e::MT_RESPONSE + && vsomeip_test::TEST_SERVICE_METHOD_ID == _response->get_method()) { + // check for calculated CRC status OK for the predefined fixed payload sent by service + VSOMEIP_INFO << "Method ID 0x8421 -> IS_VALID_CRC 8 = " << std::hex << _response->is_valid_crc(); + EXPECT_EQ(true, _response->is_valid_crc()); + + // check if payload is as expected as well (including CRC / counter / data ID nibble) + std::shared_ptr pl = _response->get_payload(); + uint8_t* dataptr = pl->get_data(); //start after length field + for(uint32_t i = 0; i< pl->get_length(); i++) { + EXPECT_EQ(dataptr[i], payloads_profile_01_[received_responses_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND][i]); + } + received_responses_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID]++; + } else if (_response->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION + && 0x8001 == _response->get_method()) { + // check CRC / payload calculated by sender for event 0x8001 against expected payload + // check for calculated CRC status OK for the calculated CRC / payload sent by service + VSOMEIP_INFO << "Event ID 0x8001 -> IS_VALID_CRC 8 = " << std::hex << _response->is_valid_crc(); + EXPECT_EQ(true, _response->is_valid_crc()); + + // check if payload is as expected as well (including CRC / counter / data ID nibble) + std::shared_ptr pl = _response->get_payload(); + uint8_t* dataptr = pl->get_data(); //start after length field + for(uint32_t i = 0; i< pl->get_length(); i++) { + EXPECT_EQ(dataptr[i], event_payloads_profile_01_[received_responses_counters_[0x8001] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND][i]); + } + received_responses_counters_[0x8001]++; + } else if (_response->get_message_type() == vsomeip::message_type_e::MT_RESPONSE + && 0x6543 == _response->get_method()) { + // check for calculated CRC status OK for the predefined fixed payload sent by service + VSOMEIP_INFO << "Method ID 0x6543 -> IS_VALID_CRC 32 = " << std::hex << _response->is_valid_crc(); + EXPECT_EQ(true, _response->is_valid_crc()); + + // check if payload is as expected as well (including CRC / counter / data ID nibble) + std::shared_ptr pl = _response->get_payload(); + uint8_t* dataptr = pl->get_data(); //start after length field + for(uint32_t i = 0; i< pl->get_length(); i++) { + EXPECT_EQ(dataptr[i], payloads_custom_profile_[received_responses_counters_[0x6543] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND][i]); + } + received_responses_counters_[0x6543]++; + } else if (_response->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION + && 0x8002 == _response->get_method()) { + VSOMEIP_INFO << "Event ID 0x8002 -> IS_VALID_CRC 32 = " << std::hex << _response->is_valid_crc(); + EXPECT_EQ(true, _response->is_valid_crc()); + + // check if payload is as expected as well (including CRC) + std::shared_ptr pl = _response->get_payload(); + uint8_t* dataptr = pl->get_data(); //start after length field + for(uint32_t i = 0; i< pl->get_length(); i++) { + EXPECT_EQ(dataptr[i], event_payloads_custom_profile_[received_responses_counters_[0x8002] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND][i]); + } + received_responses_counters_[0x8002]++; + } + + received_responses_++; + if (received_responses_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND * 4) { + VSOMEIP_WARNING << std::hex << app_->get_client() + << ": Received all messages ~> going down!"; + } +} + +void e2e_test_client::run() { + for (uint32_t i = 0; i < vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND; ++i) { + { + std::unique_lock its_lock(mutex_); + while (!is_available_) + { + condition_.wait(its_lock); + } + } + auto request = vsomeip::runtime::get()->create_request(false); + request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + + // send a request which is not e2e protected and expect an + // protected answer holding a fixed payload (profile 01 CRC8) + // this call triggers also an event 0x8001 which holds a calculated payload + request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); + app_->send(request); + + // send a request which is not e2e protected and expect an + // protected answer holding a fixed payload (custom profile CRC32) + // this call triggers also an event 0x8002 which holds a calculated payload + request->set_method(0x6543); + app_->send(request); + + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + } + stop(); +} + +void e2e_test_client::join_sender_thread() +{ + if (sender_.joinable()) { + sender_.join(); + } +} + +void e2e_test_client::shutdown_service() { + auto request = vsomeip::runtime::get()->create_request(false); + request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); + app_->send(request); + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + + // expect 10 x response messages for both method IDs and events for both Event IDs + EXPECT_EQ(received_responses_, vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND * 4); + //EXPECT_EQ(received_allowed_events_, vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND); +} + +TEST(someip_e2e_test, basic_subscribe_request_response) +{ + e2e_test_client test_client(is_remote_test, remote_client_allowed); + if (test_client.init()) { + test_client.start(); + test_client.join_sender_thread(); + } +} + +int main(int argc, char** argv) { + + /* + e2e profile01 CRC8 protected fixed sample payloads sent by service + which must be received in client using the following config on client side: + "service_id" : "0x1234", + "event_id" : "0x8421", + "profile" : "CRC8", + "variant" : "checker", + "crc_offset" : "0", + "data_id_mode" : "3", + "data_length" : "56", + "data_id" : "0xA73" + */ + payloads_profile_01_.push_back({{0x82, 0xa4, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); // initial event + payloads_profile_01_.push_back({{0x39, 0xa8, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x87, 0xa4, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x3c, 0xa8, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x55, 0xac, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x82, 0xa4, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x39, 0xa8, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x87, 0xa4, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x3c, 0xa8, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x55, 0xac, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); + + /* + e2e profile01 CRC8 protected payloads which shall be created by e2e module on + service side using the following config on client side: + "service_id" : "0x1234", + "event_id" : "0x8001", + "profile" : "CRC8", + "variant" : "checker", + "crc_offset" : "0", + "data_id_mode" : "3", + "data_length" : "56", + "data_id" : "0xA73" + */ + event_payloads_profile_01_.push_back({{0xa4, 0xa1, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff}}); // initial event + event_payloads_profile_01_.push_back({{0x05, 0xa2, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff}}); + event_payloads_profile_01_.push_back({{0x92, 0xa3, 0x02, 0xff, 0xff, 0xff, 0xff, 0xff}}); + event_payloads_profile_01_.push_back({{0x5a, 0xa4, 0x03, 0xff, 0xff, 0xff, 0xff, 0xff}}); + event_payloads_profile_01_.push_back({{0xc8, 0xa5, 0x04, 0xff, 0xff, 0xff, 0xff, 0xff}}); + event_payloads_profile_01_.push_back({{0x69, 0xa6, 0x05, 0xff, 0xff, 0xff, 0xff, 0xff}}); + event_payloads_profile_01_.push_back({{0xfe, 0xa7, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff}}); + event_payloads_profile_01_.push_back({{0xe4, 0xa8, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff}}); + event_payloads_profile_01_.push_back({{0x7c, 0xa9, 0x08, 0xff, 0xff, 0xff, 0xff, 0xff}}); + event_payloads_profile_01_.push_back({{0xdd, 0xaa, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff}}); + + /* + e2e custom profile CRR32 protected fixed sample payloads sent by service + which must be received in client using the following config on client side: + "service_id" : "0x1234", + "event_id" : "0x6543", + "profile" : "CRC32", + "variant" : "checker", + "crc_offset" : "0" + */ + payloads_custom_profile_.push_back({{0xa4, 0xb2, 0x75, 0x1f, 0xff, 0x00, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa5, 0x70, 0x1f, 0x28, 0xff, 0x01, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa7, 0x36, 0xa1, 0x71, 0xff, 0x02, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa6, 0xf4, 0xcb, 0x46, 0xff, 0x03, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa3, 0xbb, 0xdd, 0xc3, 0xff, 0x04, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa2, 0x79, 0xb7, 0xf4, 0xff, 0x05, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa0, 0x3f, 0x09, 0xad, 0xff, 0x06, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa1, 0xfd, 0x63, 0x9a, 0xff, 0x07, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xaa, 0xa1, 0x24, 0xa7, 0xff, 0x08, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xab, 0x63, 0x4e, 0x90, 0xff, 0x09, 0xff, 0x32}}); + + /* + e2e custom profile CRC32 protected payloads which shall be created by e2e module on + service side using the following config on client side for checking: + "service_id" : "0x1234", + "event_id" : "0x8002", + "profile" : "CRC32", + "variant" : "checker", + "crc_offset" : "0" + */ + event_payloads_custom_profile_.push_back({{0x89, 0x0e, 0xbc, 0x80, 0xff, 0xff, 0x00, 0x32}}); + event_payloads_custom_profile_.push_back({{0x90, 0x15, 0x8d, 0xc1, 0xff, 0xff, 0x01, 0x32}}); + event_payloads_custom_profile_.push_back({{0xbb, 0x38, 0xde, 0x02, 0xff, 0xff, 0x02, 0x32}}); + event_payloads_custom_profile_.push_back({{0xa2, 0x23, 0xef, 0x43, 0xff, 0xff, 0x03, 0x32}}); + event_payloads_custom_profile_.push_back({{0xed, 0x62, 0x79, 0x84, 0xff, 0xff, 0x04, 0x32}}); + event_payloads_custom_profile_.push_back({{0xf4, 0x79, 0x48, 0xc5, 0xff, 0xff, 0x05, 0x32}}); + event_payloads_custom_profile_.push_back({{0xdf, 0x54, 0x1b, 0x06, 0xff, 0xff, 0x06, 0x32}}); + event_payloads_custom_profile_.push_back({{0xc6, 0x4f, 0x2a, 0x47, 0xff, 0xff, 0x07, 0x32}}); + event_payloads_custom_profile_.push_back({{0x41, 0xd7, 0x36, 0x88, 0xff, 0xff, 0x08, 0x32}}); + event_payloads_custom_profile_.push_back({{0x58, 0xcc, 0x07, 0xc9, 0xff, 0xff, 0x09, 0x32}}); + + received_responses_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID] = 0; + received_responses_counters_[0x8001] = 0; + received_responses_counters_[0x6543] = 0; + received_responses_counters_[0x8002] = 0; + + std::string test_remote("--remote"); + std::string test_local("--local"); + std::string test_allow_remote_client("--allow"); + std::string test_deny_remote_client("--deny"); + std::string help("--help"); + + int i = 1; + while (i < argc) + { + if(test_remote == argv[i]) + { + is_remote_test = true; + } + else if(test_local == argv[i]) + { + is_remote_test = false; + } + else if(test_allow_remote_client == argv[i]) + { + remote_client_allowed = true; + } + else if(test_deny_remote_client == argv[i]) + { + remote_client_allowed = false; + } + else if(help == argv[i]) + { + VSOMEIP_INFO << "Parameters:\n" + << "--remote: Run test between two hosts\n" + << "--local: Run test locally\n" + << "--allow: test is started with a policy that allows remote messages sent by this test client to the service\n" + << "--deny: test is started with a policy that denies remote messages sent by this test client to the service\n" + << "--help: print this help"; + } + i++; + } + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/e2e_tests/e2e_test_client.hpp b/test/network_tests/e2e_tests/e2e_test_client.hpp new file mode 100644 index 0000000..378263c --- /dev/null +++ b/test/network_tests/e2e_tests/e2e_test_client.hpp @@ -0,0 +1,55 @@ + +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef E2E_TEST_CLIENT_HPP +#define E2E_TEST_CLIENT_HPP + +#include + +#include + +#include "../someip_test_globals.hpp" + +#include +#include +#include +#include + +class e2e_test_client { +public: + e2e_test_client(bool _test_external_communication, + bool _is_remote_client_allowed); + bool init(); + void start(); + void stop(); + + void on_state(vsomeip::state_type_e _state); + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available); + void on_message(const std::shared_ptr &_response); + + void run(); + void join_sender_thread(); + +private: + void shutdown_service(); + + std::shared_ptr app_; + + std::mutex mutex_; + std::condition_variable condition_; + bool is_available_; + + std::thread sender_; + + std::atomic received_responses_; + std::atomic received_allowed_events_; + + bool test_external_communication_; + bool is_remote_client_allowed_; +}; + +#endif // E2E_TEST_CLIENT_HPP diff --git a/test/network_tests/e2e_tests/e2e_test_external_master_start.sh b/test/network_tests/e2e_tests/e2e_test_external_master_start.sh new file mode 100755 index 0000000..16836c7 --- /dev/null +++ b/test/network_tests/e2e_tests/e2e_test_external_master_start.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# Copyright (C) 2015-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +if [ $# -lt 1 ] +then + echo "Please pass a json file to this script" + echo "For example: $0 e2e_test_client_external.json" + exit 1 +fi + +MASTER_JSON_FILE=$1 +SERVICE_JSON_FILE=${MASTER_JSON_FILE/client/service} +ALLOW_DENY=$2 + +FAIL=0 + +export VSOMEIP_CONFIGURATION=$1 +export VSOMEIP_APPLICATION_NAME=client-sample +./e2e_test_client --remote & +PID_CLIENT=$! + + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting external e2e test on slave LXC" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./e2e_test_external_slave_start.sh $SERVICE_JSON_FILE\"" & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./e2e_test_external_slave_start.sh $SERVICE_JSON_FILE" & +else +cat <> payloads_profile_01_; +std::vector> payloads_custom_profile_; +std::map received_requests_counters_; + +e2e_test_service::e2e_test_service() : + app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + blocked_(false), + number_of_received_messages_(0), + offer_thread_(std::bind(&e2e_test_service::run, this)) { +} + +bool e2e_test_service::init() { + std::lock_guard its_lock(mutex_); + + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + // profile01 CRC8 Method ID: 0x8421 + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, + std::bind(&e2e_test_service::on_message, this, + std::placeholders::_1)); + + // custom profile CRC32 Method ID: 0x6543 + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, 0x6543, + std::bind(&e2e_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, + std::bind(&e2e_test_service::on_message_shutdown, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&e2e_test_service::on_state, this, + std::placeholders::_1)); + + // offer field 0x8001 eventgroup 0x01 + std::set its_eventgroups; + its_eventgroups.insert(0x01); + + // offer field 0x8002 eventgroup 0x02 + std::set its_eventgroups_2; + its_eventgroups_2.insert(0x02); + + // profile01 CRC8 Event ID: 0x8001 + app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8001), its_eventgroups, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + + // set value to field which gets filled by e2e protection with CRC on sending + // after e2e protection the payload for first event should look like: + // {{0xa4, 0xa1, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff} + std::shared_ptr its_payload = + vsomeip::runtime::get()->create_payload(); + vsomeip::byte_t its_data[8] = {0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff}; + its_payload->set_data(its_data, 8); + + app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8001), its_payload); + + // custom profile CRC32 Event ID: 0x8002 + app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8002), its_eventgroups_2, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + + // set value to field which gets filled by e2e protection with CRC on sending + // after e2e protection the payload for first event should look like: + // {{0x89, 0x0e, 0xbc, 0x80, 0xff, 0xff, 0x00, 0x32} + std::shared_ptr its_payload_8002 = + vsomeip::runtime::get()->create_payload(); + vsomeip::byte_t its_data_8002[8] = {0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x32}; + its_payload_8002->set_data(its_data_8002, 8); + + app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8002), its_payload_8002); + + return true; +} + +void e2e_test_service::start() { + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void e2e_test_service::stop() { + VSOMEIP_INFO << "Stopping..."; + app_->clear_all_handler(); + app_->stop(); +} + +void e2e_test_service::join_offer_thread() { + if (offer_thread_.joinable()) { + offer_thread_.join(); + } +} + +void e2e_test_service::offer() { + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void e2e_test_service::stop_offer() { + app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void e2e_test_service::on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : + "deregistered."); + + if(_state == vsomeip::state_type_e::ST_REGISTERED) { + if(!is_registered_) { + is_registered_ = true; + std::lock_guard its_lock(mutex_); + blocked_ = true; + // "start" the run method thread + condition_.notify_one(); + } + } + else { + is_registered_ = false; + } +} + +void e2e_test_service::on_message(const std::shared_ptr& _request) { + ASSERT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _request->get_service()); + ASSERT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _request->get_instance()); + + VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _request->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _request->get_session() << "] method: " << _request->get_method() ; + + std::shared_ptr its_response = + vsomeip::runtime::get()->create_response(_request); + std::shared_ptr< vsomeip::payload > its_vsomeip_payload = + vsomeip::runtime::get()->create_payload(); + std::shared_ptr its_event_payload = + vsomeip::runtime::get()->create_payload(); + + // send fixed payload for profile 01 CRC8 + if (_request->get_method() == vsomeip_test::TEST_SERVICE_METHOD_ID) { + its_vsomeip_payload->set_data(payloads_profile_01_[received_requests_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND]); + its_response->set_payload(its_vsomeip_payload); + app_->send(its_response); + + // set value to field which gets filled by e2e protection with CRC on sending + vsomeip::byte_t its_data[8] = {0x00, 0x00, (uint8_t)received_requests_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID], 0xff, 0xff, 0xff, 0xff, 0xff}; + its_event_payload->set_data(its_data, 8); + app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8001), its_event_payload); + received_requests_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID]++; + } else if (_request->get_method() == 0x6543) { + //send fixed payload for custom profile CRC32 + its_vsomeip_payload->set_data(payloads_custom_profile_[received_requests_counters_[0x6543] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND]); + its_response->set_payload(its_vsomeip_payload); + app_->send(its_response); + + // set value to field which gets filled by e2e protection with 4 byte CRC 32 on sending + vsomeip::byte_t its_data[8] = {0x00, 0x00, 0x00, 0x00, 0xff, 0xff, (uint8_t)received_requests_counters_[0x6543], 0x32}; + its_event_payload->set_data(its_data, 8); + app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8002), its_event_payload); + received_requests_counters_[0x6543]++; + } + + number_of_received_messages_++; + if(number_of_received_messages_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND * 2) { + VSOMEIP_INFO << "Received all messages!"; + } +} + +void e2e_test_service::on_message_shutdown( + const std::shared_ptr& _request) { + (void)_request; + VSOMEIP_INFO << "Shutdown method was called, going down now."; + stop(); +} + +void e2e_test_service::run() { + std::unique_lock its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); + offer(); +} + +TEST(someip_e2e_test, basic_subscribe_request_response) { + e2e_test_service test_service; + if (test_service.init()) { + test_service.start(); + test_service.join_offer_thread(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) { + + /* + e2e profile01 CRC8 protected sample payloads using the following config at receiver: + "service_id" : "0x1234", + "event_id" : "0x8421", + "profile" : "CRC8", + "variant" : "checker", + "crc_offset" : "0", + "data_id_mode" : "3", + "data_length" : "56", + "data_id" : "0xA73" + */ + payloads_profile_01_.push_back({{0x82, 0xa4, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x39, 0xa8, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x87, 0xa4, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x3c, 0xa8, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x55, 0xac, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x82, 0xa4, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x39, 0xa8, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x87, 0xa4, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x3c, 0xa8, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); + payloads_profile_01_.push_back({{0x55, 0xac, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}}); + + /* + e2e custom profile CRC32 protected sample payloads using the following config at receiver: + "service_id" : "0x1234", + "event_id" : "0x6543", + "profile" : "CRC32", + "variant" : "checker", + "crc_offset" : "0" + */ + payloads_custom_profile_.push_back({{0xa4, 0xb2, 0x75, 0x1f, 0xff, 0x00, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa5, 0x70, 0x1f, 0x28, 0xff, 0x01, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa7, 0x36, 0xa1, 0x71, 0xff, 0x02, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa6, 0xf4, 0xcb, 0x46, 0xff, 0x03, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa3, 0xbb, 0xdd, 0xc3, 0xff, 0x04, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa2, 0x79, 0xb7, 0xf4, 0xff, 0x05, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa0, 0x3f, 0x09, 0xad, 0xff, 0x06, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xa1, 0xfd, 0x63, 0x9a, 0xff, 0x07, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xaa, 0xa1, 0x24, 0xa7, 0xff, 0x08, 0xff, 0x32}}); + payloads_custom_profile_.push_back({{0xab, 0x63, 0x4e, 0x90, 0xff, 0x09, 0xff, 0x32}}); + + received_requests_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID] = 0; + received_requests_counters_[0x7654] = 0; + received_requests_counters_[0x6543] = 0; + received_requests_counters_[0x5432] = 0; + + std::string test_remote("--remote"); + std::string test_local("--local"); + std::string test_allow_remote_client("--allow"); + std::string test_deny_remote_client("--deny"); + std::string help("--help"); + + int i = 1; + while (i < argc) + { + if(test_remote == argv[i]) + { + is_remote_test = true; + } + else if(test_local == argv[i]) + { + is_remote_test = false; + } + else if(test_allow_remote_client == argv[i]) + { + remote_client_allowed = true; + } + else if(test_deny_remote_client == argv[i]) + { + remote_client_allowed = false; + } + else if(help == argv[i]) + { + VSOMEIP_INFO << "Parameters:\n" + << "--remote: Run test between two hosts\n" + << "--local: Run test locally\n" + << "--allow: test is started with a policy that allows remote messages sent by this test client to the service\n" + << "--deny: test is started with a policy that denies remote messages sent by this test client to the service\n" + << "--help: print this help"; + } + i++; + } + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/e2e_tests/e2e_test_service.hpp b/test/network_tests/e2e_tests/e2e_test_service.hpp new file mode 100644 index 0000000..f7f2b96 --- /dev/null +++ b/test/network_tests/e2e_tests/e2e_test_service.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef e2e_test_SERVICE_HPP +#define e2e_test_SERVICE_HPP + +#include + +#include + +#include "../someip_test_globals.hpp" + +#include +#include +#include + +class e2e_test_service { +public: + e2e_test_service(); + bool init(); + void start(); + void stop(); + void offer(); + void stop_offer(); + void join_offer_thread(); + void on_state(vsomeip::state_type_e _state); + void on_message(const std::shared_ptr &_request); + void on_message_shutdown(const std::shared_ptr &_request); + void run(); + +private: + std::shared_ptr app_; + bool is_registered_; + + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + std::uint32_t number_of_received_messages_; + std::thread offer_thread_; +}; + +#endif // E2E_TEST_SERVICE_HPP diff --git a/test/network_tests/event_tests/conf/event_test_master.json.in b/test/network_tests/event_tests/conf/event_test_master.json.in new file mode 100644 index 0000000..b8db14f --- /dev/null +++ b/test/network_tests/event_tests/conf/event_test_master.json.in @@ -0,0 +1,32 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications" : + [ + { + "name" : "event_test_client", + "id" : "0x3489", + "max_dispatch_time" : "1000" + } + ], + "routing":"routingmanagerd", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.50.1", + "port":"30490", + "protocol":"udp", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/event_tests/conf/event_test_slave_tcp.json.in b/test/network_tests/event_tests/conf/event_test_slave_tcp.json.in new file mode 100644 index 0000000..d0bbed9 --- /dev/null +++ b/test/network_tests/event_tests/conf/event_test_slave_tcp.json.in @@ -0,0 +1,43 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications" : + [ + { + "name" : "event_test_service", + "id" : "0x1210", + "max_dispatch_time" : "1000" + } + ], + "services": + [ + { + "service":"0x3344", + "instance":"0x0001", + "reliable": { + "port":"40001", + "enable-magic-cookies":"false" + } + } + ], + "routing":"routingmanagerd", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.50.1", + "port":"30490", + "protocol":"udp", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/event_tests/conf/event_test_slave_udp.json.in b/test/network_tests/event_tests/conf/event_test_slave_udp.json.in new file mode 100644 index 0000000..6bf693b --- /dev/null +++ b/test/network_tests/event_tests/conf/event_test_slave_udp.json.in @@ -0,0 +1,40 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications" : + [ + { + "name" : "event_test_service", + "id" : "0x1210", + "max_dispatch_time" : "1000" + } + ], + "services": + [ + { + "service":"0x3344", + "instance":"0x0001", + "unreliable":"30001" + } + ], + "routing":"routingmanagerd", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.50.1", + "port":"30490", + "protocol":"udp", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/event_tests/event_test_client.cpp b/test/network_tests/event_tests/event_test_client.cpp new file mode 100644 index 0000000..e183d8c --- /dev/null +++ b/test/network_tests/event_tests/event_test_client.cpp @@ -0,0 +1,284 @@ +// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "event_test_globals.hpp" + +class event_test_client { +public: + event_test_client(struct event_test::service_info _service_info, event_test::test_mode_e _mode, + bool _use_tcp) : + service_info_(_service_info), + test_mode_(_mode), + use_tcp_(_use_tcp), + app_(vsomeip::runtime::get()->create_application("event_test_client")), + service_available_(false), + wait_until_registered_(true), + wait_until_service_available_(true), + wait_until_subscription_accepted_(true), + wait_until_events_received_(true), + wait_until_shutdown_reply_received_(true), + number_events_to_send_(50), + number_events_received_(0), + send_thread_(std::bind(&event_test_client::send, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&event_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, + std::bind(&event_test_client::on_message, this, + std::placeholders::_1)); + + // register availability for all other services and request their event. + app_->register_availability_handler(service_info_.service_id, + service_info_.instance_id, + std::bind(&event_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + app_->request_service(service_info_.service_id, + service_info_.instance_id); + + std::set its_eventgroups; + its_eventgroups.insert(service_info_.eventgroup_id); + app_->request_event(service_info_.service_id, + service_info_.instance_id, service_info_.event_id, + its_eventgroups, vsomeip::event_type_e::ET_EVENT, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); + app_->register_subscription_status_handler(service_info_.service_id, + service_info_.instance_id, service_info_.eventgroup_id, + service_info_.event_id, + std::bind(&event_test_client::on_subscription_status_changed, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4, + std::placeholders::_5)); + app_->subscribe(service_info_.service_id, service_info_.instance_id, + service_info_.eventgroup_id); + + app_->start(); + } + + ~event_test_client() { + send_thread_.join(); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + VSOMEIP_INFO << "Service [" << std::setw(4) + << std::setfill('0') << std::hex << _service << "." << _instance + << "] is " << (_is_available ? "available":"not available") << "."; + if (_is_available) { + std::lock_guard its_lock(mutex_); + wait_until_service_available_ = false; + condition_.notify_one(); + } + } + + void on_message(const std::shared_ptr &_message) { + if(_message->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + on_notification(_message); + } else if (_message->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + on_response(_message); + } + } + + void on_notification(const std::shared_ptr &_message) { + EXPECT_EQ(service_info_.service_id, _message->get_service()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + EXPECT_EQ(service_info_.event_id, _message->get_method()); + if (test_mode_ == event_test::test_mode_e::PAYLOAD_FIXED) { + EXPECT_EQ(event_test::payload_fixed_length, _message->get_payload()->get_length()); + } else if (test_mode_ == event_test::test_mode_e::PAYLOAD_DYNAMIC) { + static vsomeip::length_t length_last_received_msg(0); + EXPECT_GT(_message->get_payload()->get_length(), length_last_received_msg); + length_last_received_msg = _message->get_payload()->get_length(); + + } + if (++number_events_received_ == number_events_to_send_) { + std::lock_guard its_lock(mutex_); + wait_until_events_received_ = false; + condition_.notify_one(); + } + + VSOMEIP_DEBUG + << "Received a notification with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_session() << "] from Service/Method [" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_service() << "/" << std::setw(4) << std::setfill('0') + << std::hex << _message->get_method() <<"]"; + + } + + void on_response(const std::shared_ptr &_message) { + EXPECT_EQ(service_info_.service_id, _message->get_service()); + EXPECT_EQ(service_info_.shutdown_method_id, _message->get_method()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + std::lock_guard its_lock(mutex_); + wait_until_shutdown_reply_received_ = false; + condition_.notify_one(); + } + + void on_subscription_status_changed(const vsomeip::service_t _service, + const vsomeip::instance_t _instance, + const vsomeip::eventgroup_t _eventgroup, + const vsomeip::event_t _event, + const uint16_t error_code) { + EXPECT_EQ(service_info_.service_id, _service); + EXPECT_EQ(service_info_.instance_id, _instance); + EXPECT_EQ(service_info_.eventgroup_id, _eventgroup); + EXPECT_EQ(service_info_.event_id, _event); + EXPECT_TRUE((error_code == 0x0u || error_code == 0x7u)); + if (error_code == 0x0u) { // accepted + std::lock_guard its_lock(mutex_); + wait_until_subscription_accepted_ = false; + condition_.notify_one(); + } + } + + void send() { + { + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + while (wait_until_service_available_) { + condition_.wait(its_lock); + } + + while (wait_until_subscription_accepted_) { + if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { + VSOMEIP_ERROR << "Subscription wasn't accepted in time!"; + break; + } + } + + // call notify method + auto its_message = vsomeip::runtime::get()->create_request(use_tcp_); + its_message->set_service(service_info_.service_id); + its_message->set_instance(service_info_.instance_id); + its_message->set_method(service_info_.notify_method_id); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + auto its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data(std::vector({ + static_cast(test_mode_), + static_cast(number_events_to_send_)})); + its_message->set_payload(its_payload); + app_->send(its_message); + + while (wait_until_events_received_) { + if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { + VSOMEIP_ERROR << "Didn't receive events in time!"; + break; + } + } + + // shutdown service + its_message->set_method(service_info_.shutdown_method_id); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST); + app_->send(its_message); + + while (wait_until_shutdown_reply_received_) { + if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { + VSOMEIP_ERROR << "Shutdown request wasn't answered in time!"; + break; + } + } + } + VSOMEIP_INFO << "going down"; + app_->clear_all_handler(); + app_->stop(); + } + + +private: + struct event_test::service_info service_info_; + event_test::test_mode_e test_mode_; + bool use_tcp_; + std::shared_ptr app_; + bool service_available_; + + bool wait_until_registered_; + bool wait_until_service_available_; + bool wait_until_subscription_accepted_; + bool wait_until_events_received_; + bool wait_until_shutdown_reply_received_; + std::mutex mutex_; + std::condition_variable condition_; + + const std::uint8_t number_events_to_send_; + std::atomic number_events_received_; + std::thread send_thread_; +}; + +static event_test::test_mode_e passed_mode = event_test::test_mode_e::PAYLOAD_FIXED; +static bool use_tcp = false; + +TEST(someip_event_test, subscribe_or_call_method_at_service) +{ + event_test_client its_sample(event_test::service, passed_mode, use_tcp); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if (argc < 3) { + std::cerr << "Please specify a operation mode, like: " << argv[0] << "PAYLOAD_FIXED TCP" << std::endl; + std::cerr << "Valid operation modes are PAYLOAD_FIXED and PAYLOAD_DYNAMIC" << std::endl; + std::cerr << "Valid communication modes are UDP or TCP" << std::endl; + return 1; + } + + if (std::string("PAYLOAD_FIXED") == std::string(argv[1])) { + passed_mode = event_test::test_mode_e::PAYLOAD_FIXED; + } else if (std::string("PAYLOAD_DYNAMIC") == std::string(argv[1])) { + passed_mode = event_test::test_mode_e::PAYLOAD_DYNAMIC; + } else { + std::cerr << "Wrong operation mode passed, exiting" << std::endl; + std::cerr << "Please specify a operation mode, like: " << argv[0] << " PAYLOAD_FIXED" << std::endl; + std::cerr << "Valid operation modes are PAYLOAD_FIXED and PAYLOAD_DYNAMIC" << std::endl; + return 1; + } + if (std::string("TCP")== std::string(argv[2])) { + use_tcp = true; + } else if (std::string("UDP")== std::string(argv[2])) { + use_tcp = false; + } + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/event_tests/event_test_globals.hpp b/test/network_tests/event_tests/event_test_globals.hpp new file mode 100644 index 0000000..733c3c6 --- /dev/null +++ b/test/network_tests/event_tests/event_test_globals.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EVENT_TEST_GLOBALS_HPP_ +#define EVENT_TEST_GLOBALS_HPP_ + +namespace event_test { + +struct service_info { + vsomeip::service_t service_id; + vsomeip::instance_t instance_id; + vsomeip::method_t method_id; + vsomeip::event_t event_id; + vsomeip::eventgroup_t eventgroup_id; + vsomeip::method_t shutdown_method_id; + vsomeip::method_t notify_method_id; +}; + +struct service_info service = { 0x3344, 0x1, 0x1111, 0x8002, 0x1, 0x1404, 0x4242 }; + +enum test_mode_e : std::uint8_t { + UNKNOWN, + PAYLOAD_FIXED, + PAYLOAD_DYNAMIC +}; + +std::uint32_t payload_fixed_length = 20; + +} + +#endif /* EVENT_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/event_tests/event_test_master_starter.sh b/test/network_tests/event_tests/event_test_master_starter.sh new file mode 100755 index 0000000..61dc9bc --- /dev/null +++ b/test/network_tests/event_tests/event_test_master_starter.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# Copyright (C) 2015-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 + +if [ $# -lt 2 ] +then + echo "Please pass a operation and communication mode to this script." + echo "For example: $0 PAYLOAD_FIXED UDP" + echo "Valid operation modes include [PAYLOAD_FIXED, PAYLOAD_DYNAMIC]" + echo "Valid communication modes include [UDP, TCP]" + exit 1 +fi +TESTMODE=$1 +COMMUNICATIONMODE=$2 + +export VSOMEIP_CONFIGURATION=event_test_master.json +../../examples/routingmanagerd/./routingmanagerd & +PID_VSOMEIPD=$! + +./event_test_client $TESTMODE $COMMUNICATIONMODE & +PID_CLIENT=$! + +sleep 1 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting offer test on slave LXC offer_test_external_slave_starter.sh" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./event_test_slave_starter.sh $COMMUNICATIONMODE\"" & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && sleep 10; ./event_test_slave_starter.sh $COMMUNICATIONMODE" & +else +cat < +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "event_test_globals.hpp" + +class event_test_service { +public: + event_test_service(struct event_test::service_info _service_info, bool _use_tcp) : + service_info_(_service_info), + test_mode_(event_test::test_mode_e::UNKNOWN), + app_(vsomeip::runtime::get()->create_application("event_test_service")), + wait_until_registered_(true), + wait_until_notify_method_called_(true), + wait_until_shutdown_method_called_(true), + client_subscribed_(false), + notifications_to_send_(0), + offer_thread_(std::bind(&event_test_service::run, this)), + use_tcp_(_use_tcp) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&event_test_service::on_state, this, + std::placeholders::_1)); + + std::set its_eventgroups; + its_eventgroups.insert(_service_info.eventgroup_id); + app_->offer_event(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_eventgroups, + vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), + false, true, nullptr, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.shutdown_method_id, + std::bind(&event_test_service::on_shutdown_method_called, this, + std::placeholders::_1)); + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.notify_method_id, + std::bind(&event_test_service::on_message, this, + std::placeholders::_1)); + app_->register_subscription_handler(service_info_.service_id, + service_info_.instance_id, service_info_.eventgroup_id, + std::bind(&event_test_service::subscription_handler, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4)); + + app_->start(); + } + + ~event_test_service() { + offer_thread_.join(); + } + + void offer() { + app_->offer_service(service_info_.service_id, service_info_.instance_id); + } + + void stop() { + app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); + app_->clear_all_handler(); + app_->stop(); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_shutdown_method_called(const std::shared_ptr &_message) { + app_->send(vsomeip::runtime::get()->create_response(_message)); + VSOMEIP_WARNING << "************************************************************"; + VSOMEIP_WARNING << "Shutdown method called -> going down!"; + VSOMEIP_WARNING << "************************************************************"; + std::lock_guard its_lock(mutex_); + wait_until_shutdown_method_called_ = false; + condition_.notify_one(); + } + + void on_message(const std::shared_ptr &_message) { + EXPECT_EQ(service_info_.service_id, _message->get_service()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + EXPECT_EQ(service_info_.notify_method_id, _message->get_method()); + auto its_payload = _message->get_payload(); + ASSERT_EQ(2u, its_payload->get_length()); + test_mode_ = static_cast(its_payload->get_data()[0]); + notifications_to_send_ = static_cast(its_payload->get_data()[1]); + std::lock_guard its_lock(mutex_); + wait_until_notify_method_called_ = false; + condition_.notify_one(); + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + + while (wait_until_notify_method_called_) { + condition_.wait(its_lock); + } + VSOMEIP_INFO << "notify"; + notify(); + + + while (wait_until_shutdown_method_called_) { + condition_.wait(its_lock); + } + its_lock.unlock(); + stop(); + } + + void notify() { + EXPECT_TRUE(client_subscribed_); + auto its_payload = vsomeip::runtime::get()->create_payload(); + for (std::uint32_t i = 0; i < notifications_to_send_; i++) { + if (test_mode_ == event_test::test_mode_e::PAYLOAD_FIXED) { + its_payload->set_data(std::vector(event_test::payload_fixed_length, 0x44)); + } else if (test_mode_ == event_test::test_mode_e::PAYLOAD_DYNAMIC) { + its_payload->set_data(std::vector(i+1, 0x55)); + } + app_->notify(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_payload, false); + } + } + + bool subscription_handler(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) { + (void)_uid; + (void)_gid; + VSOMEIP_INFO << __func__ << ": client: 0x" << std::hex << _client + << ((_subscribed) ? " subscribed" : "unsubscribed"); + client_subscribed_ = _subscribed; + return true; + } + +private: + struct event_test::service_info service_info_; + event_test::test_mode_e test_mode_; + std::shared_ptr app_; + + bool wait_until_registered_; + bool wait_until_notify_method_called_; + bool wait_until_shutdown_method_called_; + std::atomic client_subscribed_; + std::uint32_t notifications_to_send_; + std::mutex mutex_; + std::condition_variable condition_; + std::thread offer_thread_; + bool use_tcp_; +}; + +static bool use_tcp = false; + +TEST(someip_event_test, send_events) +{ + event_test_service its_sample(event_test::service, use_tcp); +} + + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + + if (std::string("TCP")== std::string(argv[1])) { + use_tcp = true; + } else if (std::string("UDP")== std::string(argv[1])) { + use_tcp = false; + } + + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/event_tests/event_test_slave_starter.sh b/test/network_tests/event_tests/event_test_slave_starter.sh new file mode 100755 index 0000000..c1bd489 --- /dev/null +++ b/test/network_tests/event_tests/event_test_slave_starter.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# Copyright (C) 2015-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 + +if [ $# -lt 1 ] +then + echo "Please pass a operation and communication mode to this script." + echo "For example: $0 UDP" + echo "Valid communication modes include [UDP, TCP]" + exit 1 +fi +COMMUNICATIONMODE=$1 + +if [ "$COMMUNICATIONMODE" = "TCP" ]; then + export VSOMEIP_CONFIGURATION=event_test_slave_tcp.json +elif [ "$COMMUNICATIONMODE" = "UDP" ]; then + export VSOMEIP_CONFIGURATION=event_test_slave_udp.json +fi + + +../../examples/routingmanagerd/./routingmanagerd & +PID_VSOMEIPD=$! + +./event_test_service $COMMUNICATIONMODE & +PID_SERVICE=$! + +# Wait until all clients and services are finished +for job in $PID_SERVICE +do + # Fail gets incremented if a client exits with a non-zero exit code + echo "waiting for $job" + wait $job || FAIL=$(($FAIL+1)) +done + +# kill the services +kill $PID_VSOMEIPD +sleep 1 + +# Check if everything went well +exit $FAIL diff --git a/test/network_tests/header_factory_tests/header_factory_test.cpp b/test/network_tests/header_factory_tests/header_factory_test.cpp new file mode 100644 index 0000000..14abf92 --- /dev/null +++ b/test/network_tests/header_factory_tests/header_factory_test.cpp @@ -0,0 +1,119 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include "../someip_test_globals.hpp" + +class someip_header_factory_test: public ::testing::Test +{ +protected: + std::shared_ptr request_; + std::shared_ptr response_; + std::shared_ptr notification_; + std::shared_ptr app_; + std::shared_ptr message_; + + vsomeip::service_t service_id_ = vsomeip_test::TEST_SERVICE_SERVICE_ID; + vsomeip::method_t method_id_ = vsomeip_test::TEST_SERVICE_METHOD_ID; + vsomeip::instance_t instance_id_ = vsomeip_test::TEST_SERVICE_INSTANCE_ID; + vsomeip::interface_version_t interface_version_ = 0x01; + vsomeip::client_t client_id_ = vsomeip_test::TEST_CLIENT_CLIENT_ID; + vsomeip::session_t session_id_ = vsomeip_test::TEST_INITIAL_SESSION_ID; +}; + +TEST_F(someip_header_factory_test, create_request_test) +{ + ASSERT_TRUE(request_.get() == nullptr); + request_ = vsomeip::runtime::get()->create_request(); + + // check that returned shared_ptr is not null + ASSERT_TRUE(request_.get() != nullptr); + + // Check the protocol version + // this shall be set to 0x01 according to the spec. TR_SOMEIP_00052 + ASSERT_EQ(request_->get_protocol_version(), 0x01); + // Check the message type + // this shall be 0x00 (REQUEST) according to the spec. TR_SOMEIP_00055 + ASSERT_EQ(request_->get_message_type(), vsomeip::message_type_e::MT_REQUEST); + // Check the return code + // this shall be 0x00 (E_OK) according to the spec. TR_SOMEIP_00058 + ASSERT_EQ(request_->get_return_code(), vsomeip::return_code_e::E_OK); + +} + +TEST_F(someip_header_factory_test, create_request_and_response_test) +{ + ASSERT_TRUE(request_.get() == nullptr); + request_ = vsomeip::runtime::get()->create_request(); + // check that returned shared_ptr is not null + ASSERT_TRUE(request_.get() != nullptr); + + request_->set_service(service_id_); + request_->set_method(method_id_); + request_->set_interface_version(interface_version_); + // set the request_id (client_id + session_id). This normally is set by the + // application_impl::send() if a request is send, we set it here to test the + // correct initialization of the response + request_->set_client(client_id_); + request_->set_session(session_id_); + + ASSERT_TRUE(response_.get() == nullptr); + response_ = vsomeip::runtime::get()->create_response(request_); + // check that returned shared_ptr is not null + ASSERT_TRUE(response_.get() != nullptr); + + ASSERT_EQ(response_->get_service(), request_->get_service()); + ASSERT_EQ(response_->get_method(), request_->get_method()); + ASSERT_EQ(response_->get_session(), request_->get_session()); + + // length? --> gets only set if a payload is added + + ASSERT_EQ(response_->get_protocol_version(), request_->get_protocol_version()); + ASSERT_EQ(response_->get_interface_version(), request_->get_interface_version()); + + // Check the message type + // this shall be 0x00 (REQUEST) according to the spec. TR_SOMEIP_00055 + ASSERT_EQ(request_->get_message_type(), vsomeip::message_type_e::MT_REQUEST); + + // Check the message type + // this shall be 0x80 (RESPONSE) according to the spec. TR_SOMEIP_00055 + ASSERT_EQ(response_->get_message_type(), vsomeip::message_type_e::MT_RESPONSE); + + // Check the return code + // this shall be 0x00 (E_OK) according to the spec. TR_SOMEIP_00058 + // and TR_SOMEIP_00191 + ASSERT_EQ(response_->get_return_code(), vsomeip::return_code_e::E_OK); + +} + +TEST_F(someip_header_factory_test, create_notification_test) +{ + ASSERT_TRUE(notification_.get() == nullptr); + notification_ = vsomeip::runtime::get()->create_notification(); + + // check that returned shared_ptr is not null + ASSERT_TRUE(notification_.get() != nullptr); + + // Check the protocol version + // this shall be set to 0x01 according to the spec. TR_SOMEIP_00052 + ASSERT_EQ(notification_->get_protocol_version(), 0x01); + // Check the message type + // this shall be 0x02 (NOTIFICATION) according to the spec. TR_SOMEIP_00055 + ASSERT_EQ(notification_->get_message_type(), vsomeip::message_type_e::MT_NOTIFICATION); + // Check the return code + // this shall be 0x00 (E_OK) according to the spec. TR_SOMEIP_00058 + ASSERT_EQ(notification_->get_return_code(), vsomeip::return_code_e::E_OK); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/header_factory_tests/header_factory_test_client.cpp b/test/network_tests/header_factory_tests/header_factory_test_client.cpp new file mode 100644 index 0000000..3435dea --- /dev/null +++ b/test/network_tests/header_factory_tests/header_factory_test_client.cpp @@ -0,0 +1,170 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "header_factory_test_client.hpp" + +header_factory_test_client::header_factory_test_client(bool _use_tcp) : + app_(vsomeip::runtime::get()->create_application()), + request_(vsomeip::runtime::get()->create_request(_use_tcp)), + blocked_(false), + is_available_(false), + number_of_messages_to_send_(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND), + number_of_sent_messages_(0), + number_of_acknowledged_messages_(0), + sender_(std::bind(&header_factory_test_client::run, this)) +{ +} + +bool header_factory_test_client::init() +{ + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + + app_->register_state_handler( + std::bind(&header_factory_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, + std::bind(&header_factory_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&header_factory_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + return true; +} + +void header_factory_test_client::start() +{ + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void header_factory_test_client::stop() +{ + VSOMEIP_INFO << "Stopping..."; + app_->clear_all_handler(); + app_->stop(); +} + +void header_factory_test_client::join_sender_thread(){ + sender_.join(); + + ASSERT_EQ(number_of_sent_messages_, number_of_acknowledged_messages_); +} + +void header_factory_test_client::on_state(vsomeip::state_type_e _state) +{ + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); + } +} + +void header_factory_test_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) +{ + VSOMEIP_INFO << "Service [" << std::setw(4) << std::setfill('0') << std::hex + << _service << "." << _instance << "] is " + << (_is_available ? "available." : "NOT available."); + + if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service + && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) + { + if(is_available_ && !_is_available) + { + is_available_ = false; + } + else if(_is_available && !is_available_) + { + is_available_ = true; + send(); + } + } +} + +void header_factory_test_client::on_message(const std::shared_ptr& _response) +{ + VSOMEIP_INFO << "Received a response from Service [" << std::setw(4) + << std::setfill('0') << std::hex << _response->get_service() << "." + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_instance() << "] to Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_client() << "/" << std::setw(4) + << std::setfill('0') << std::hex << _response->get_session() << "]"; + number_of_acknowledged_messages_++; + ASSERT_EQ(_response->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID); + ASSERT_EQ(_response->get_instance(), vsomeip_test::TEST_SERVICE_INSTANCE_ID); + ASSERT_EQ(_response->get_session(), + static_cast(number_of_acknowledged_messages_)); + if(number_of_acknowledged_messages_ == number_of_messages_to_send_) { + std::lock_guard its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); + } +} + +void header_factory_test_client::send() +{ + std::lock_guard its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); +} + +void header_factory_test_client::run() +{ + std::unique_lock its_lock(mutex_); + while (!blocked_) + { + condition_.wait(its_lock); + } + blocked_ = false; + request_->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request_->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + request_->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); + + for (uint32_t i = 0; i < number_of_messages_to_send_; i++) + { + app_->send(request_); + VSOMEIP_INFO << "Client/Session [" << std::setw(4) << std::setfill('0') + << std::hex << request_->get_client() << "/" << std::setw(4) + << std::setfill('0') << std::hex << request_->get_session() + << "] sent a request to Service [" << std::setw(4) + << std::setfill('0') << std::hex << request_->get_service() + << "." << std::setw(4) << std::setfill('0') << std::hex + << request_->get_instance() << "]"; + number_of_sent_messages_++; + } + // wait until all messages have been acknowledged + while (!blocked_) + { + condition_.wait(its_lock); + } + stop(); +} + +TEST(someip_header_factory_test, send_message_ten_times_test) +{ + bool use_tcp = false; + header_factory_test_client test_client_(use_tcp); + if (test_client_.init()) { + test_client_.start(); + test_client_.join_sender_thread(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/header_factory_tests/header_factory_test_client.hpp b/test/network_tests/header_factory_tests/header_factory_test_client.hpp new file mode 100644 index 0000000..8e9a4c2 --- /dev/null +++ b/test/network_tests/header_factory_tests/header_factory_test_client.hpp @@ -0,0 +1,48 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef HEADERFACTORYTESTCLIENT_HPP_ +#define HEADERFACTORYTESTCLIENT_HPP_ + +#include + +#include + +#include +#include +#include +#include + +#include "../someip_test_globals.hpp" + +class header_factory_test_client +{ +public: + header_factory_test_client(bool _use_tcp); + bool init(); + void start(); + void stop(); + void join_sender_thread(); + void on_state(vsomeip::state_type_e _state); + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available); + void on_message(const std::shared_ptr &_response); + void send(); + void run(); + +private: + std::shared_ptr app_; + std::shared_ptr request_; + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + bool is_available_; + std::uint32_t number_of_messages_to_send_; + std::uint32_t number_of_sent_messages_; + std::uint32_t number_of_acknowledged_messages_; + std::thread sender_; +}; + +#endif /* HEADERFACTORYTESTCLIENT_HPP_ */ diff --git a/test/network_tests/header_factory_tests/header_factory_test_client.json b/test/network_tests/header_factory_tests/header_factory_test_client.json new file mode 100644 index 0000000..71bc75b --- /dev/null +++ b/test/network_tests/header_factory_tests/header_factory_test_client.json @@ -0,0 +1,97 @@ +{ + "unicast" : "127.0.0.1", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "true", + "path" : "/var/log/vsomeip.log" + }, + + "dlt" : "true" + }, + + "applications" : + [ + { + "name" : "header_factory_test_client", + "id" : "0x1343" + } + ], + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unreliable" : "30509", + "events" : + [ + { + "event" : "0x0777", + "is_field" : "true" + }, + + { + "event" : "0x0778", + "is_field" : "false" + }, + + { + "event" : "0x0779", + "is_field" : "true" + } + ], + + "eventgroups" : + [ + { + "eventgroup" : "0x4455", + "events" : + [ + "0x777", + "0x778" + ] + }, + + { + "eventgroup" : "0x4465", + "events" : + [ + "0x778", + "0x779" + ], + + "is_multicast" : "true" + }, + + { + "eventgroup" : "0x4555", + "events" : + [ + "0x777", + "0x779" + ] + } + ] + } + ], + + "routing" : "header_factory_test_service", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30491", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "100", + "repetitions_base_delay" : "200", + "repetitions_max" : "3", + "ttl" : "3", + "cyclic_offer_delay" : "2000", + "request_response_delay" : "1500" + } +} \ No newline at end of file diff --git a/test/network_tests/header_factory_tests/header_factory_test_client_start.sh b/test/network_tests/header_factory_tests/header_factory_test_client_start.sh new file mode 100755 index 0000000..4e9c1ed --- /dev/null +++ b/test/network_tests/header_factory_tests/header_factory_test_client_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +export VSOMEIP_APPLICATION_NAME=header_factory_test_client +export VSOMEIP_CONFIGURATION=header_factory_test_client.json +./header_factory_test_client diff --git a/test/network_tests/header_factory_tests/header_factory_test_send_receive_starter.sh b/test/network_tests/header_factory_tests/header_factory_test_send_receive_starter.sh new file mode 100755 index 0000000..5d1d780 --- /dev/null +++ b/test/network_tests/header_factory_tests/header_factory_test_send_receive_starter.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit sucessfully. + +# Start the service +export VSOMEIP_APPLICATION_NAME=header_factory_test_service +export VSOMEIP_CONFIGURATION=header_factory_test_service.json +./header_factory_test_service & +sleep 1; + +# Start the client +export VSOMEIP_APPLICATION_NAME=header_factory_test_client +export VSOMEIP_CONFIGURATION=header_factory_test_client.json +./header_factory_test_client & + +# Wait until client and service are finished +FAIL=0 +for job in $(jobs -p) +do + # Fail gets incremented if either client or service exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +# Check if client and server both exited sucessfully +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/header_factory_tests/header_factory_test_service.cpp b/test/network_tests/header_factory_tests/header_factory_test_service.cpp new file mode 100644 index 0000000..4caca7a --- /dev/null +++ b/test/network_tests/header_factory_tests/header_factory_test_service.cpp @@ -0,0 +1,170 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "header_factory_test_service.hpp" + +#include + +header_factory_test_service::header_factory_test_service(bool _use_static_routing) : + app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + use_static_routing_(_use_static_routing), + blocked_(false), + number_of_received_messages_(0), + offer_thread_(std::bind(&header_factory_test_service::run, this)) +{ +} + +bool header_factory_test_service::init() +{ + std::lock_guard its_lock(mutex_); + + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, + std::bind(&header_factory_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&header_factory_test_service::on_state, this, + std::placeholders::_1)); + + VSOMEIP_INFO << "Static routing " << (use_static_routing_ ? "ON" : "OFF"); + return true; +} + +void header_factory_test_service::start() +{ + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void header_factory_test_service::stop() +{ + VSOMEIP_INFO << "Stopping..."; + app_->clear_all_handler(); + app_->stop(); + std::thread t([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 5));}); + t.join(); +} + +void header_factory_test_service::join_offer_thread() +{ + offer_thread_.join(); +} + +void header_factory_test_service::offer() +{ + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void header_factory_test_service::stop_offer() +{ + app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void header_factory_test_service::on_state(vsomeip::state_type_e _state) +{ + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : + "deregistered."); + + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + if(!is_registered_) + { + is_registered_ = true; + std::lock_guard its_lock(mutex_); + blocked_ = true; + // "start" the run method thread + condition_.notify_one(); + } + } + else + { + is_registered_ = false; + } +} + +void header_factory_test_service::on_message(const std::shared_ptr& _request) +{ + VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _request->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _request->get_session() << "]"; + + number_of_received_messages_++; + + ASSERT_EQ(_request->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID); + ASSERT_EQ(_request->get_method(), vsomeip_test::TEST_SERVICE_METHOD_ID); + + // Check the protocol version this shall be set to 0x01 according to the spec. + // TR_SOMEIP_00052 + ASSERT_EQ(_request->get_protocol_version(), 0x01); + // Check the message type this shall be 0xx (REQUEST) according to the spec. + // TR_SOMEIP_00055 + ASSERT_EQ(_request->get_message_type(), vsomeip::message_type_e::MT_REQUEST); + + // check the session id. + ASSERT_EQ(_request->get_session(), static_cast(number_of_received_messages_)); + + + // send response + std::shared_ptr its_response = + vsomeip::runtime::get()->create_response(_request); + + app_->send(its_response); + + if(number_of_received_messages_ >= vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND) + { + std::lock_guard its_lock(mutex_); + blocked_ =true; + condition_.notify_one(); + } + ASSERT_LT(number_of_received_messages_, + vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND + 1); +} + +void header_factory_test_service::run() +{ + std::unique_lock its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); + + blocked_ = false; + if(use_static_routing_) + { + offer(); + } + while (!blocked_) + condition_.wait(its_lock); + + std::thread t([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 5));}); + t.join(); + app_->stop(); +} + +TEST(someip_header_factory_test, reveice_message_ten_times_test) +{ + bool use_static_routing = true; + header_factory_test_service test_service(use_static_routing); + if (test_service.init()) { + test_service.start(); + test_service.join_offer_thread(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/header_factory_tests/header_factory_test_service.hpp b/test/network_tests/header_factory_tests/header_factory_test_service.hpp new file mode 100644 index 0000000..32e49e5 --- /dev/null +++ b/test/network_tests/header_factory_tests/header_factory_test_service.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef HEADERFACTORYTESTSERVICE_HPP_ +#define HEADERFACTORYTESTSERVICE_HPP_ +#include + +#include + +#include +#include +#include +#include + +#include "../someip_test_globals.hpp" + +class header_factory_test_service +{ +public: + header_factory_test_service(bool _use_static_routing); + bool init(); + void start(); + void stop(); + void offer(); + void stop_offer(); + void join_offer_thread(); + void on_state(vsomeip::state_type_e _state); + void on_message(const std::shared_ptr &_request); + void run(); + +private: + std::shared_ptr app_; + bool is_registered_; + bool use_static_routing_; + + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + std::uint32_t number_of_received_messages_; + std::thread offer_thread_; +}; + +#endif /* HEADERFACTORYTESTSERVICE_HPP_ */ diff --git a/test/network_tests/header_factory_tests/header_factory_test_service.json b/test/network_tests/header_factory_tests/header_factory_test_service.json new file mode 100644 index 0000000..a99d0a2 --- /dev/null +++ b/test/network_tests/header_factory_tests/header_factory_test_service.json @@ -0,0 +1,105 @@ +{ + "unicast" : "127.0.0.1", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/tmp/vsomeip.log" + }, + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "header_factory_test_service", + "id" : "0x1277" + } + ], + + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unreliable" : "30509", + "multicast" : + { + "address" : "224.225.226.233", + "port" : "32344" + }, + + "events" : + [ + { + "event" : "0x0777", + "is_field" : "true", + "update-cycle" : 2000 + }, + + { + "event" : "0x0778", + "is_field" : "true", + "update-cycle" : 0 + }, + + { + "event" : "0x0779", + "is_field" : "true" + } + ], + + "eventgroups" : + [ + { + "eventgroup" : "0x4455", + "events" : + [ + "0x777", + "0x778" + ] + }, + + { + "eventgroup" : "0x4465", + "events" : + [ + "0x778", + "0x779" + ], + + "is_multicast" : "true" + }, + + { + "eventgroup" : "0x4555", + "events" : + [ + "0x777", + "0x779" + ] + } + ] + } + ], + + "routing" : "header_factory_test_service", + + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "100", + "repetitions_base_delay" : "200", + "repetitions_max" : "3", + "ttl" : "3", + "cyclic_offer_delay" : "2000", + "request_response_delay" : "1500" + } +} \ No newline at end of file diff --git a/test/network_tests/header_factory_tests/header_factory_test_service_start.sh b/test/network_tests/header_factory_tests/header_factory_test_service_start.sh new file mode 100755 index 0000000..e123a46 --- /dev/null +++ b/test/network_tests/header_factory_tests/header_factory_test_service_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=header_factory_test_service +export VSOMEIP_CONFIGURATION=header_factory_test_service.json +./header_factory_test_service diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master.json.in new file mode 100644 index 0000000..d7b5c7b --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master.json.in @@ -0,0 +1,81 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_one", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_two", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x8888", + "instance":"0x0001", + "unreliable":"8888" + } + ], + "routing":"initial_event_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in new file mode 100644 index 0000000..a05d13f --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in @@ -0,0 +1,78 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_one", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_two", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x8888", + "instance":"0x0001", + "unreliable":"8888" + } + ], + "routing":"initial_event_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_udp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_udp.json.in new file mode 100644 index 0000000..8ce06f0 --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_udp.json.in @@ -0,0 +1,66 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_one", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_two", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001" + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002" + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003" + }, + { + "service":"0x8888", + "instance":"0x0001", + "unreliable":"8888" + } + ], + "routing":"initial_event_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json.in new file mode 100644 index 0000000..6445025 --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_master.json.in @@ -0,0 +1,81 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_one", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_two", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1111", + "instance":"0x0002", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x1111", + "instance":"0x0003", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x8888", + "instance":"0x0001", + "unreliable":"8888" + } + ], + "routing":"initial_event_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json.in new file mode 100644 index 0000000..c5dddc3 --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_same_service_id_slave.json.in @@ -0,0 +1,82 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "diagnosis" : "0x63", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_four", + "id":"0x4444" + }, + { + "name":"initial_event_test_service_five", + "id":"0x5555" + }, + { + "name":"initial_event_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0002", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0003", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x9999", + "instance":"0x0001", + "unreliable":"9999" + } + ], + "routing":"initial_event_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave.json.in new file mode 100644 index 0000000..3e7e286 --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave.json.in @@ -0,0 +1,82 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "diagnosis" : "0x63", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_four", + "id":"0x4444" + }, + { + "name":"initial_event_test_service_five", + "id":"0x5555" + }, + { + "name":"initial_event_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x9999", + "instance":"0x0001", + "unreliable":"9999" + } + ], + "routing":"initial_event_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in new file mode 100644 index 0000000..1fc97a4 --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in @@ -0,0 +1,79 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "diagnosis" : "0x63", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_four", + "id":"0x4444" + }, + { + "name":"initial_event_test_service_five", + "id":"0x5555" + }, + { + "name":"initial_event_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x9999", + "instance":"0x0001", + "unreliable":"9999" + } + ], + "routing":"initial_event_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_udp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_udp.json.in new file mode 100644 index 0000000..d303a4c --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_udp.json.in @@ -0,0 +1,67 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "diagnosis" : "0x63", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_four", + "id":"0x4444" + }, + { + "name":"initial_event_test_service_five", + "id":"0x5555" + }, + { + "name":"initial_event_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004" + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005" + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006" + }, + { + "service":"0x9999", + "instance":"0x0001", + "unreliable":"9999" + } + ], + "routing":"initial_event_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_master.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_master.json.in new file mode 100644 index 0000000..f168fae --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_master.json.in @@ -0,0 +1,81 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_one", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_two", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x8888", + "instance":"0x0001", + "unreliable":"8888" + } + ], + "routing":"initial_event_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_slave.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_slave.json.in new file mode 100644 index 0000000..30206a2 --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_partial_same_ports_slave.json.in @@ -0,0 +1,82 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "diagnosis" : "0x63", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_four", + "id":"0x4444" + }, + { + "name":"initial_event_test_service_five", + "id":"0x5555" + }, + { + "name":"initial_event_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x9999", + "instance":"0x0001", + "unreliable":"9999" + } + ], + "routing":"initial_event_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master.json.in new file mode 100644 index 0000000..785e651 --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master.json.in @@ -0,0 +1,81 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_one", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_two", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x8888", + "instance":"0x0001", + "unreliable":"8888" + } + ], + "routing":"initial_event_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in new file mode 100644 index 0000000..b065685 --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in @@ -0,0 +1,78 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_one", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_two", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x8888", + "instance":"0x0001", + "unreliable":"8888" + } + ], + "routing":"initial_event_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_udp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_udp.json.in new file mode 100644 index 0000000..ca77daf --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_udp.json.in @@ -0,0 +1,66 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_one", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_two", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x8888", + "instance":"0x0001", + "unreliable":"8888" + } + ], + "routing":"initial_event_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave.json.in new file mode 100644 index 0000000..cfbdac4 --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave.json.in @@ -0,0 +1,82 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "diagnosis" : "0x63", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_four", + "id":"0x4444" + }, + { + "name":"initial_event_test_service_five", + "id":"0x5555" + }, + { + "name":"initial_event_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x9999", + "instance":"0x0001", + "unreliable":"9999" + } + ], + "routing":"initial_event_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in new file mode 100644 index 0000000..eaeab4a --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in @@ -0,0 +1,79 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "diagnosis" : "0x63", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_four", + "id":"0x4444" + }, + { + "name":"initial_event_test_service_five", + "id":"0x5555" + }, + { + "name":"initial_event_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x9999", + "instance":"0x0001", + "unreliable":"9999" + } + ], + "routing":"initial_event_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_udp.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_udp.json.in new file mode 100644 index 0000000..5d978f0 --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_udp.json.in @@ -0,0 +1,67 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "diagnosis" : "0x63", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_four", + "id":"0x4444" + }, + { + "name":"initial_event_test_service_five", + "id":"0x5555" + }, + { + "name":"initial_event_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x9999", + "instance":"0x0001", + "unreliable":"9999" + } + ], + "routing":"initial_event_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_master.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_master.json.in new file mode 100644 index 0000000..d7b5c7b --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_master.json.in @@ -0,0 +1,81 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_one", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_two", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x8888", + "instance":"0x0001", + "unreliable":"8888" + } + ], + "routing":"initial_event_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_slave.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_slave.json.in new file mode 100644 index 0000000..facc51a --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_diff_ports_slave.json.in @@ -0,0 +1,82 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "diagnosis" : "0x63", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_four", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_five", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_six", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x9999", + "instance":"0x0001", + "unreliable":"9999" + } + ], + "routing":"initial_event_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_master.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_master.json.in new file mode 100644 index 0000000..785e651 --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_master.json.in @@ -0,0 +1,81 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_one", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_two", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x8888", + "instance":"0x0001", + "unreliable":"8888" + } + ], + "routing":"initial_event_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_slave.json.in b/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_slave.json.in new file mode 100644 index 0000000..97b5d9f --- /dev/null +++ b/test/network_tests/initial_event_tests/conf/initial_event_test_same_client_ids_same_ports_slave.json.in @@ -0,0 +1,82 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "diagnosis" : "0x63", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_four", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_five", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_six", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x9999", + "instance":"0x0001", + "unreliable":"9999" + } + ], + "routing":"initial_event_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/initial_event_tests/initial_event_test_availability_checker.cpp b/test/network_tests/initial_event_tests/initial_event_test_availability_checker.cpp new file mode 100644 index 0000000..f05b592 --- /dev/null +++ b/test/network_tests/initial_event_tests/initial_event_test_availability_checker.cpp @@ -0,0 +1,165 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "initial_event_test_globals.hpp" + + +class initial_event_test_availability_checker { +public: + initial_event_test_availability_checker(int _client_number, + std::array _service_infos) : + client_number_(_client_number), + service_infos_(_service_infos), + app_(vsomeip::runtime::get()->create_application()), + wait_until_registered_(true), + wait_for_stop_(true), + stop_thread_(std::bind(&initial_event_test_availability_checker::wait_for_stop, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&initial_event_test_availability_checker::on_state, this, + std::placeholders::_1)); + + // register availability for all other services and request their event. + for(const auto& i : service_infos_) { + if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) { + continue; + } + other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; + app_->register_availability_handler(i.service_id, i.instance_id, + std::bind(&initial_event_test_availability_checker::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + app_->request_service(i.service_id, i.instance_id); + } + + app_->start(); + } + + ~initial_event_test_availability_checker() { + stop_thread_.join(); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + if(_is_available) { + auto its_service = other_services_available_.find(std::make_pair(_service, _instance)); + if(its_service != other_services_available_.end()) { + if(its_service->second != _is_available) { + its_service->second = true; + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << client_number_ << "] Service [" + << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance + << "] is available."; + + } + } + + if(std::all_of(other_services_available_.cbegin(), + other_services_available_.cend(), + [](const std::map, bool>::value_type& v) { + return v.second;})) { + + std::lock_guard its_lock(stop_mutex_); + wait_for_stop_ = false; + stop_condition_.notify_one(); + } + } + } + + void wait_for_stop() { + std::unique_lock its_lock(stop_mutex_); + while (wait_for_stop_) { + stop_condition_.wait(its_lock); + } + VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex + << client_number_ << "] all services are available. Going down"; + app_->clear_all_handler(); + app_->stop(); + } + +private: + int client_number_; + std::array service_infos_; + std::shared_ptr app_; + std::map, bool> other_services_available_; + + bool wait_until_registered_; + std::mutex mutex_; + std::condition_variable condition_; + + bool wait_for_stop_; + std::mutex stop_mutex_; + std::condition_variable stop_condition_; + std::thread stop_thread_; +}; + +static int client_number; +static bool use_same_service_id; + +TEST(someip_initial_event_test, wait_for_availability_and_exit) +{ + if(use_same_service_id) { + initial_event_test_availability_checker its_sample(client_number, + initial_event_test::service_infos_same_service_id); + } else { + initial_event_test_availability_checker its_sample(client_number, + initial_event_test::service_infos); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a client number and subscription type, like: " << argv[0] << " 2 SAME_SERVICE_ID" << std::endl; + std::cerr << "Valid client numbers are from 0 to 0xFFFF" << std::endl; + std::cerr << "If SAME_SERVICE_ID is specified as third parameter the test is run w/ multiple instances of the same service" << std::endl; + return 1; + } + + client_number = std::stoi(std::string(argv[1]), nullptr); + + if (argc >= 2) { + for (int i = 2; i < argc; i++) { + if (std::string("SAME_SERVICE_ID") == std::string(argv[i])) { + use_same_service_id = true; + std::cout << "Availability checker: Using same service ID" << std::endl; + } + } + } + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/initial_event_tests/initial_event_test_client.cpp b/test/network_tests/initial_event_tests/initial_event_test_client.cpp new file mode 100644 index 0000000..ba549ab --- /dev/null +++ b/test/network_tests/initial_event_tests/initial_event_test_client.cpp @@ -0,0 +1,635 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if defined(__linux__) || defined(ANDROID) +#include +#endif + +#include +#include + +#include "initial_event_test_globals.hpp" + +class initial_event_test_client; +static initial_event_test_client* the_client; +extern "C" void signal_handler(int _signum); + +class initial_event_test_client { +public: + initial_event_test_client(int _client_number, + bool _service_offered_tcp_and_udp, + std::array _service_infos, + bool _subscribe_on_available, std::uint32_t _events_to_subscribe, + bool _initial_event_strict_checking, + bool _dont_exit, bool _subscribe_only_one, + vsomeip::reliability_type_e _reliability_type, + bool _client_subscribes_twice) : + client_number_(_client_number), + service_infos_(_service_infos), + service_offered_tcp_and_udp_(_service_offered_tcp_and_udp), + app_(vsomeip::runtime::get()->create_application()), + wait_until_registered_(true), + wait_for_stop_(true), + is_first(true), + subscribe_on_available_(_subscribe_on_available), + events_to_subscribe_(_events_to_subscribe), + initial_event_strict_checking_(_initial_event_strict_checking), + dont_exit_(_dont_exit), + subscribe_only_one_(_subscribe_only_one), + stop_thread_(&initial_event_test_client::wait_for_stop, this), + wait_for_signal_handler_registration_(true), + reliability_type_(_reliability_type), + client_subscribes_twice_(_client_subscribes_twice) + { + if (!app_->init()) { + stop_thread_.detach(); + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + + app_->register_state_handler( + std::bind(&initial_event_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, + std::bind(&initial_event_test_client::on_message, this, + std::placeholders::_1)); + + // register availability for all other services and request their event. + for(const auto& i : service_infos_) { + if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) { + continue; + } + app_->register_availability_handler(i.service_id, i.instance_id, + std::bind(&initial_event_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + app_->request_service(i.service_id, i.instance_id); + + std::set its_eventgroups; + its_eventgroups.insert(i.eventgroup_id); + for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) { + app_->request_event(i.service_id, i.instance_id, + static_cast(i.event_id + j), + its_eventgroups, vsomeip::event_type_e::ET_FIELD, + reliability_type_); + } + + other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; + + if (!subscribe_on_available_) { + if (events_to_subscribe_ == 1) { + app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, + vsomeip::DEFAULT_MAJOR); + + std::lock_guard its_lock(received_notifications_mutex_); + other_services_received_notification_[std::make_pair(i.service_id, i.event_id)] = 0; + } else if (events_to_subscribe_ > 1) { + if (!subscribe_only_one_) { + for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) { + app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, + vsomeip::DEFAULT_MAJOR, + static_cast(i.event_id + j)); + std::lock_guard its_lock(received_notifications_mutex_); + other_services_received_notification_[std::make_pair(i.service_id, i.event_id + j)] = 0; + } + } else { + app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, + vsomeip::DEFAULT_MAJOR, + static_cast(i.event_id)); + other_services_received_notification_[std::make_pair(i.service_id, i.event_id)] = 0; + } + } + } else { + for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) { + other_services_received_notification_[std::make_pair(i.service_id, i.event_id + j)] = 0; + } + } + } + + // Block all signals + sigset_t mask; + sigfillset(&mask); + pthread_sigmask(SIG_BLOCK, &mask, NULL); + // start thread which handles all of the signals + signal_thread_ = std::thread(&initial_event_test_client::wait_for_signal, this); + { + std::unique_lock its_lock(signal_mutex_); + while(wait_for_signal_handler_registration_) { + EXPECT_EQ(std::cv_status::no_timeout, + signal_condition_.wait_for(its_lock, std::chrono::seconds(10))); + } + wait_for_signal_handler_registration_ = true; + } + + app_->start(); + } + + ~initial_event_test_client() { + if (stop_thread_.joinable()) { + stop_thread_.join(); + } + if (signal_thread_.joinable()) { + signal_thread_.join(); + } + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + if(_is_available) { + auto its_service = other_services_available_.find(std::make_pair(_service, _instance)); + if(its_service != other_services_available_.end()) { + if(its_service->second != _is_available) { + its_service->second = true; + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << client_number_ << "] Service [" + << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance + << "] is available."; + + } + } + + if(std::all_of(other_services_available_.cbegin(), + other_services_available_.cend(), + [](const std::map, bool>::value_type& v) { + return v.second;})) { + VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex + << client_number_ << "] all services are available."; + if (subscribe_on_available_) { + for(const auto& i : service_infos_) { + if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) { + continue; + } + if (events_to_subscribe_ == 1 ) { + app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, + vsomeip::DEFAULT_MAJOR); + } else if (events_to_subscribe_ > 1) { + for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) { + app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, + vsomeip::DEFAULT_MAJOR, + static_cast(i.event_id + j)); + } + } + } + } + } + } + } + + void on_message(const std::shared_ptr &_message) { + if(_message->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + + { + std::lock_guard its_lock(received_notifications_mutex_); + other_services_received_notification_[std::make_pair(_message->get_service(), + _message->get_method())]++; + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << client_number_ << "] " + << "Received a notification with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_session() << "] from Service/Method [" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_service() << "/" << std::setw(4) << std::setfill('0') + << std::hex << _message->get_method() <<"] (now have: " + << std::dec << other_services_received_notification_[std::make_pair(_message->get_service(), + _message->get_method())] << ")"; + } + + std::shared_ptr its_payload(_message->get_payload()); + EXPECT_EQ(2u, its_payload->get_length()); + EXPECT_EQ((_message->get_service() & 0xFF00 ) >> 8, its_payload->get_data()[0]); + EXPECT_EQ((_message->get_service() & 0xFF), its_payload->get_data()[1]); + bool notify(false); + if (client_subscribes_twice_) { + // only relevant for testcase: + // initial_event_test_diff_client_ids_same_ports_udp_client_subscribes_twice + // check that a second subscribe triggers another initial event + // expect notifications_to_send_after_double_subscribe == 2; + if (is_first) { + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + for(const auto& i : service_infos_) { + // subscribe again and expect initial events cached at rm::proxy to be received + // as configured routing manager only fires the event once after first susbcribe. + if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) { + continue; + } + if (!subscribe_on_available_) { + if (events_to_subscribe_ == 1) { + app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, + vsomeip::DEFAULT_MAJOR); + } else if (events_to_subscribe_ > 1) { + if (!subscribe_only_one_) { + for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) { + app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, + vsomeip::DEFAULT_MAJOR, + static_cast(i.event_id + j)); + } + } else { + app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, + vsomeip::DEFAULT_MAJOR, + static_cast(i.event_id)); + } + } + } + } + is_first = false; + } else { + bool received_initial_event_twice(false); + std::lock_guard its_lock(received_notifications_mutex_); + received_initial_event_twice = all_notifications_received_twice(); + if (received_initial_event_twice) { + notify = true; + } + } + } else { + if (!service_offered_tcp_and_udp_) { + std::lock_guard its_lock(received_notifications_mutex_); + if (all_notifications_received()) { + notify = true; + } + } else { + if (all_notifications_received_tcp_and_udp()) { + notify = true; + } + } + } + + if (notify && !dont_exit_) { + std::lock_guard its_lock(stop_mutex_); + wait_for_stop_ = false; + stop_condition_.notify_one(); + } + } + } + + bool all_notifications_received() { + return std::all_of( + other_services_received_notification_.cbegin(), + other_services_received_notification_.cend(), + [&](const std::map, std::uint32_t>::value_type& v) + { + bool result; + if (v.second == initial_event_test::notifications_to_send) { + result = true; + } else { + if (v.second >= initial_event_test::notifications_to_send) { + VSOMEIP_WARNING + << "[" << std::setw(4) << std::setfill('0') << std::hex + << client_number_ << "] " + << " Received multiple initial events from service/instance: " + << std::setw(4) << std::setfill('0') << std::hex << v.first.first + << "." + << std::setw(4) << std::setfill('0') << std::hex << v.first.second + << " number of received events: " << v.second + << ". This is caused by StopSubscribe/Subscribe messages and/or" + << " service offered via UDP and TCP"; + if (initial_event_strict_checking_) { + ADD_FAILURE() << "[" << std::setw(4) << std::setfill('0') << std::hex + << client_number_ << "] " + << " Received multiple initial events from service/instance: " + << std::setw(4) << std::setfill('0') << std::hex << v.first.first + << "." + << std::setw(4) << std::setfill('0') << std::hex << v.first.second + << " number of received events: " << v.second; + } + result = initial_event_strict_checking_ ? false : true; + + } else { + result = false; + } + } + + return result; + } + ); + } + + bool all_notifications_received_twice() { + return std::all_of( + other_services_received_notification_.cbegin(), + other_services_received_notification_.cend(), + [&](const std::map, std::uint32_t>::value_type& v) + { + bool result; + if (v.second == initial_event_test::notifications_to_send * 2) { + result = true; + } else { + if (v.second >= initial_event_test::notifications_to_send * 2) { + VSOMEIP_WARNING + << __func__ << "[" << std::setw(4) << std::setfill('0') << std::hex + << client_number_ << "] " + << " Received multiple initial events from service/instance: " + << std::setw(4) << std::setfill('0') << std::hex << v.first.first + << "." + << std::setw(4) << std::setfill('0') << std::hex << v.first.second + << " number of received events: " << v.second + << ". This is caused by StopSubscribe/Subscribe messages and/or" + << " service offered via UDP and TCP"; + if (initial_event_strict_checking_) { + ADD_FAILURE() << __func__ << "[" << std::setw(4) << std::setfill('0') << std::hex + << client_number_ << "] " + << " Received multiple initial events from service/instance: " + << std::setw(4) << std::setfill('0') << std::hex << v.first.first + << "." + << std::setw(4) << std::setfill('0') << std::hex << v.first.second + << " number of received events: " << v.second; + } + result = initial_event_strict_checking_ ? false : true; + + } else { + result = false; + } + } + return result; + } + ); + } + + bool all_notifications_received_tcp_and_udp() { + std::lock_guard its_lock(received_notifications_mutex_); + std::uint32_t received_twice(0); + std::uint32_t received_normal(0); + for(const auto &v : other_services_received_notification_) { + if (!initial_event_strict_checking_ && + v.second > initial_event_test::notifications_to_send * 2) { + VSOMEIP_WARNING + << "[" << std::setw(4) << std::setfill('0') << std::hex + << client_number_ << "] " + << " Received multiple initial events from service/instance: " + << std::setw(4) << std::setfill('0') << std::hex << v.first.first + << "." + << std::setw(4) << std::setfill('0') << std::hex << v.first.second + << ". This is caused by StopSubscribe/Subscribe messages and/or" + << " service offered via UDP and TCP"; + received_twice++; + } else if (initial_event_strict_checking_ && + v.second > initial_event_test::notifications_to_send * 2) { + ADD_FAILURE() << "[" << std::setw(4) << std::setfill('0') << std::hex + << client_number_ << "] " + << " Received multiple initial events from service/instance: " + << std::setw(4) << std::setfill('0') << std::hex << v.first.first + << "." + << std::setw(4) << std::setfill('0') << std::hex << v.first.second + << " number of received events: " << v.second; + } else if (v.second == initial_event_test::notifications_to_send * 2) { + received_twice++; + } else if(v.second == initial_event_test::notifications_to_send) { + received_normal++; + } + } + + if( received_twice == ((service_infos_.size() - 1) * events_to_subscribe_)/ 2 + && received_normal == ((service_infos_.size() - 1) * events_to_subscribe_)/ 2) { + // routing manager stub receives the notification + // - twice from external nodes + // - and normal from all internal nodes + VSOMEIP_ERROR << "[" << std::setw(4) << std::setfill('0') << std::hex + << client_number_ << "] " + << "Received notifications:" + << " Normal: " << received_normal + << " Twice: " << received_twice; + return true; + } else if (initial_event_strict_checking_ && ( + received_twice > ((service_infos_.size() - 1) * events_to_subscribe_)/ 2)) { + ADD_FAILURE() << "[" << std::setw(4) << std::setfill('0') << std::hex + << client_number_ << "] " + << " Received too much initial events twice: " << received_twice; + } else if (received_normal == (events_to_subscribe_ * (service_infos_.size() - 1))) { + return true; + } + return false; + } + + void wait_for_signal() { + // register signal handler + the_client = this; + + sigset_t handler_mask; + sigemptyset(&handler_mask); + sigaddset(&handler_mask, SIGUSR1); + sigaddset(&handler_mask, SIGTERM); + sigaddset(&handler_mask, SIGINT); + sigaddset(&handler_mask, SIGABRT); + pthread_sigmask(SIG_UNBLOCK, &handler_mask, NULL); + + struct sigaction sa_new, sa_old; + sa_new.sa_handler = signal_handler; + sa_new.sa_flags = 0; + sigemptyset(&sa_new.sa_mask); + ::sigaction(SIGUSR1, &sa_new, &sa_old); + ::sigaction(SIGINT, &sa_new, &sa_old); + ::sigaction(SIGTERM, &sa_new, &sa_old); + ::sigaction(SIGABRT, &sa_new, &sa_old); + + { + std::lock_guard its_lock(signal_mutex_); + wait_for_signal_handler_registration_ = false; + signal_condition_.notify_one(); + } + while (wait_for_stop_) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + } + + void handle_signal(int _signum) { + (void)_signum; + std::lock_guard its_lock(stop_mutex_); + wait_for_stop_ = false; + stop_condition_.notify_one(); + } + + void wait_for_stop() { + static int its_call_number(0); + its_call_number++; + + { + std::unique_lock its_lock(stop_mutex_); + while (wait_for_stop_) { + stop_condition_.wait_for(its_lock, std::chrono::milliseconds(100)); + } + VSOMEIP_ERROR << "(" << std::dec << its_call_number << ") [" + << std::setw(4) << std::setfill('0') << std::hex + << client_number_ + << "] Received notifications from all services, going down"; + } + for (const auto& i : service_infos_) { + if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) { + continue; + } + app_->unsubscribe(i.service_id, i.instance_id, i.eventgroup_id); + } + app_->clear_all_handler(); + app_->stop(); + } + +private: + int client_number_; + std::array service_infos_; + bool service_offered_tcp_and_udp_; + std::shared_ptr app_; + std::map, bool> other_services_available_; + std::mutex received_notifications_mutex_; + std::map, std::uint32_t> other_services_received_notification_; + + bool wait_until_registered_; + std::mutex mutex_; + std::condition_variable condition_; + + std::atomic wait_for_stop_; + std::atomic is_first; + + bool subscribe_on_available_; + std::uint32_t events_to_subscribe_; + bool initial_event_strict_checking_; + bool dont_exit_; + bool subscribe_only_one_; + + std::mutex stop_mutex_; + std::condition_variable stop_condition_; + std::thread stop_thread_; + bool wait_for_signal_handler_registration_; + std::mutex signal_mutex_; + std::condition_variable signal_condition_; + std::thread signal_thread_; + vsomeip::reliability_type_e reliability_type_; + bool client_subscribes_twice_; +}; + +static int client_number; +static bool service_offered_tcp_and_udp; +static bool use_same_service_id; +static bool subscribe_on_available; +static std::uint32_t subscribe_multiple_events; +static bool initial_event_strict_checking; +static bool dont_exit; +static bool subscribe_only_one; +static bool client_subscribes_twice; + +vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN; + + +extern "C" void signal_handler(int signum) { + the_client->handle_signal(signum); +} + +TEST(someip_initial_event_test, wait_for_initial_events_of_all_services) +{ + if(use_same_service_id) { + initial_event_test_client its_sample(client_number, + service_offered_tcp_and_udp, + initial_event_test::service_infos_same_service_id, + subscribe_on_available, subscribe_multiple_events, + initial_event_strict_checking, dont_exit, + subscribe_only_one, + reliability_type, + client_subscribes_twice); + } else { + initial_event_test_client its_sample(client_number, service_offered_tcp_and_udp, + initial_event_test::service_infos, subscribe_on_available, + subscribe_multiple_events, initial_event_strict_checking, dont_exit, + subscribe_only_one, + reliability_type, + client_subscribes_twice); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + // Block all signals + sigset_t mask; + sigfillset(&mask); + pthread_sigmask(SIG_BLOCK, &mask, NULL); + ::testing::InitGoogleTest(&argc, argv); + + if(argc < 2) { + std::cerr << "Please specify a client number, like: " << argv[0] << " 2 SUBSCRIBE_BEFORE_START SAME_SERVICE_ID" << std::endl; + std::cerr << "Valid client numbers are from 0 to 0xFFFF" << std::endl; + std::cerr << "After client number one/multiple of these flags can be specified:"; + std::cerr << " - SERVICE_OFFERED_TCP_AND_UDP flag. Set this if the service is offered via TCP and UDP" << std::endl; + std::cerr << " - Time of subscription, valid values: [SUBSCRIBE_ON_AVAILABILITY, SUBSCRIBE_BEFORE_START], default SUBSCRIBE_BEFORE_START" << std::endl; + std::cerr << " - SAME_SERVICE_ID flag. If set the test is run w/ multiple instances of the same service, default false" << std::endl; + std::cerr << " - MULTIPLE_EVENTS flag. If set the test will subscribe to multiple events in the eventgroup, default false" << std::endl; + std::cerr << " - STRICT_CHECKING flag. If set the test will only successfully finish if exactly the number of initial events were received (and not more). Default false" << std::endl; + std::cerr << " - DONT_EXIT flag. If set the test will not exit if all notifications have been received. Default false" << std::endl; + std::cerr << " - SUBSCRIBE_ONLY_ONE flag. If set the test will only subscribe to one event even if MULTIPLE_EVENTS is set. Default false" << std::endl; + return 1; + } + + client_number = std::stoi(std::string(argv[1]), nullptr); + + subscribe_on_available = false; + initial_event_strict_checking = false; + service_offered_tcp_and_udp = false; + use_same_service_id = false; + subscribe_multiple_events = 1; + dont_exit = false; + subscribe_only_one = false; + client_subscribes_twice = false; + if (argc > 2) { + for (int i = 2; i < argc; i++) { + if (std::string("SUBSCRIBE_ON_AVAILABILITY") == std::string(argv[i])) { + subscribe_on_available = true; + } else if (std::string("SUBSCRIBE_BEFORE_START") == std::string(argv[i])) { + subscribe_on_available = false; + } else if (std::string("SAME_SERVICE_ID") == std::string(argv[i])) { + use_same_service_id = true; + std::cout << "Using same service ID" << std::endl; + } else if (std::string("MULTIPLE_EVENTS") == std::string(argv[i])) { + subscribe_multiple_events = 5; + } else if (std::string("STRICT_CHECKING") == std::string(argv[i])) { + initial_event_strict_checking = true; + } else if (std::string("DONT_EXIT") == std::string(argv[i])) { + dont_exit = true; + } else if (std::string("SUBSCRIBE_ONLY_ONE") == std::string(argv[i])) { + subscribe_only_one = true; + } else if (std::string("TCP")== std::string(argv[i])) { + reliability_type = vsomeip::reliability_type_e::RT_RELIABLE; + std::cout << "Using reliability type RT_RELIABLE" << std::endl; + } else if (std::string("UDP")== std::string(argv[i])) { + reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE; + std::cout << "Using reliability type RT_UNRELIABLE" << std::endl; + } else if (std::string("TCP_AND_UDP")== std::string(argv[i])) { + reliability_type = vsomeip::reliability_type_e::RT_BOTH; + std::cout << "Using reliability type RT_BOTH" << std::endl; + } else if (std::string("CLIENT_SUBSCRIBES_TWICE")== std::string(argv[i])) { + client_subscribes_twice = true; + std::cout << "Testing for initial event after a second subscribe from same client CLIENT_SUBSCRIBES_TWICE" << std::endl; + } + } + } + + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/initial_event_tests/initial_event_test_globals.hpp b/test/network_tests/initial_event_tests/initial_event_test_globals.hpp new file mode 100644 index 0000000..ce69ea9 --- /dev/null +++ b/test/network_tests/initial_event_tests/initial_event_test_globals.hpp @@ -0,0 +1,51 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ +#define SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ + +namespace initial_event_test { + +struct service_info { + vsomeip::service_t service_id; + vsomeip::instance_t instance_id; + vsomeip::method_t method_id; + vsomeip::event_t event_id; + vsomeip::eventgroup_t eventgroup_id; +}; + +static constexpr std::array service_infos = {{ + // placeholder to be consistent w/ client ids, service ids, app names + { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }, + // node 1 + { 0x1111, 0x1, 0x1111, 0x1111, 0x1000 }, + { 0x2222, 0x1, 0x2222, 0x2222, 0x2000 }, + { 0x3333, 0x1, 0x3333, 0x3333, 0x3000 }, + // node 2 + { 0x4444, 0x1, 0x4444, 0x4444, 0x4000 }, + { 0x5555, 0x1, 0x5555, 0x5555, 0x5000 }, + { 0x6666, 0x1, 0x6666, 0x6666, 0x6000 } +}}; + +static constexpr std::array service_infos_same_service_id = {{ + // placeholder to be consistent w/ client ids, service ids, app names + { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }, + // node 1 + { 0x1111, 0x1, 0x1111, 0x1111, 0x1000 }, + { 0x1111, 0x2, 0x2222, 0x2222, 0x2000 }, + { 0x1111, 0x3, 0x3333, 0x3333, 0x3000 }, + // node 2 + { 0x2222, 0x1, 0x4444, 0x4444, 0x4000 }, + { 0x2222, 0x2, 0x5555, 0x5555, 0x5000 }, + { 0x2222, 0x3, 0x6666, 0x6666, 0x6000 } +}}; + +static constexpr service_info stop_service_master = { 0x8888, 0x1, 0x8888, 0x0, 0x0 }; +static constexpr service_info stop_service_slave = { 0x9999, 0x1, 0x9999, 0x0, 0x0 }; + +static constexpr int notifications_to_send = 1; +} + +#endif /* SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/initial_event_tests/initial_event_test_master_starter.sh b/test/network_tests/initial_event_tests/initial_event_test_master_starter.sh new file mode 100755 index 0000000..9d52e3f --- /dev/null +++ b/test/network_tests/initial_event_tests/initial_event_test_master_starter.sh @@ -0,0 +1,143 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +if [ $# -lt 1 ] +then + echo "Please pass a json file to this script." + echo "For example: $0 initial_event_test_diff_client_ids_diff_ports_master.json" + echo "To use the same service id but different instances on the node pass SAME_SERVICE_ID as third parameter" + echo "To ensure the first client only subscribes to one event pass SUBSCRIBE_ONLY_ONE as third/fourth parameter" + exit 1 +fi + +PASSED_JSON_FILE=$1 +# Remove processed options from $@ +shift 1 +REMAINING_OPTIONS="$@" + +print_starter_message () { + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting initial event test on slave LXC with params $CLIENT_JSON_FILE $REMAINING_OPTIONS" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./initial_event_test_slave_starter.sh $CLIENT_JSON_FILE $REMAINING_OPTIONS\"" & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./initial_event_test_slave_starter.sh $CLIENT_JSON_FILE $REMAINING_OPTIONS" & +else +cat < +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "initial_event_test_globals.hpp" + + +class initial_event_test_service { +public: + initial_event_test_service(struct initial_event_test::service_info _service_info, + std::uint32_t _events_to_offer, vsomeip::reliability_type_e _reliability_type) : + service_info_(_service_info), + app_(vsomeip::runtime::get()->create_application()), + wait_until_registered_(true), + events_to_offer_(_events_to_offer), + offer_thread_(std::bind(&initial_event_test_service::run, this)), + reliability_type_(_reliability_type) { + if (!app_->init()) { + offer_thread_.detach(); + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&initial_event_test_service::on_state, this, + std::placeholders::_1)); + + // offer field + std::set its_eventgroups; + its_eventgroups.insert(service_info_.eventgroup_id); + for (std::uint16_t i = 0; i < events_to_offer_; i++) { + app_->offer_event(service_info_.service_id, service_info_.instance_id, + static_cast(service_info_.event_id + i), + its_eventgroups, vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), false, true, nullptr, + reliability_type_); + } + + // set value to field + std::shared_ptr its_payload = + vsomeip::runtime::get()->create_payload(); + vsomeip::byte_t its_data[2] = {static_cast((service_info_.service_id & 0xFF00) >> 8), + static_cast((service_info_.service_id & 0xFF))}; + its_payload->set_data(its_data, 2); + for (std::uint16_t i = 0; i < events_to_offer_; i++) { + app_->notify(service_info_.service_id, service_info_.instance_id, + static_cast(service_info_.event_id + i), its_payload); + } + + app_->start(); + } + + ~initial_event_test_service() { + if (offer_thread_.joinable()) { + offer_thread_.join(); + } + } + + void offer() { + app_->offer_service(service_info_.service_id, service_info_.instance_id); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + } + +private: + initial_event_test::service_info service_info_; + std::shared_ptr app_; + + bool wait_until_registered_; + std::uint32_t events_to_offer_; + std::mutex mutex_; + std::condition_variable condition_; + std::thread offer_thread_; + vsomeip::reliability_type_e reliability_type_; +}; + +static unsigned long service_number; +static bool use_same_service_id; +static std::uint32_t offer_multiple_events; +vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN; + +TEST(someip_initial_event_test, set_field_once) +{ + if(use_same_service_id) { + initial_event_test_service its_sample( + initial_event_test::service_infos_same_service_id[service_number], offer_multiple_events, + reliability_type); + } else { + initial_event_test_service its_sample( + initial_event_test::service_infos[service_number], offer_multiple_events, + reliability_type); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a service number and subscription type, like: " << argv[0] << " 2 SAME_SERVICE_ID" << std::endl; + std::cerr << "Valid service numbers are in the range of [1,6]" << std::endl; + std::cerr << "After the service number one/multiple of these flags can be specified:"; + std::cerr << " - SAME_SERVICE_ID flag. If set the test is run w/ multiple instances of the same service, default false" << std::endl; + std::cerr << " - MULTIPLE_EVENTS flag. If set the test will offer to multiple events in the eventgroup, default false" << std::endl; + return 1; + } + + service_number = std::stoul(std::string(argv[1]), nullptr); + + offer_multiple_events = 1; + use_same_service_id = false; + + if (argc > 2) { + for (int i = 2; i < argc; i++) { + if (std::string("SAME_SERVICE_ID") == std::string(argv[i])) { + use_same_service_id = true; + std::cout << "Using same service ID" << std::endl; + } else if (std::string("MULTIPLE_EVENTS") == std::string(argv[i])) { + offer_multiple_events = 5; + } else if (std::string("TCP")== std::string(argv[i])) { + reliability_type = vsomeip::reliability_type_e::RT_RELIABLE; + std::cout << "Using reliability type RT_RELIABLE" << std::endl; + } else if (std::string("UDP")== std::string(argv[i])) { + reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE; + std::cout << "Using reliability type RT_UNRELIABLE" << std::endl; + } else if (std::string("TCP_AND_UDP")== std::string(argv[i])) { + reliability_type = vsomeip::reliability_type_e::RT_BOTH; + std::cout << "Using reliability type RT_BOTH" << std::endl; + } + } + } + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/initial_event_tests/initial_event_test_slave_starter.sh b/test/network_tests/initial_event_tests/initial_event_test_slave_starter.sh new file mode 100755 index 0000000..6aea217 --- /dev/null +++ b/test/network_tests/initial_event_tests/initial_event_test_slave_starter.sh @@ -0,0 +1,104 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +if [ $# -lt 1 ] +then + echo "Please pass a json file to this script." + echo "For example: $0 initial_event_test_diff_client_ids_diff_ports_slave.json UDP" + echo "To use the same service id but different instances on the node pass SAME_SERVICE_ID as third parameter" + echo "To ensure the first client only subscribes to one event pass SUBSCRIBE_ONLY_ONE as third/fourth parameter" + exit 1 +fi + +PASSED_JSON_FILE=$1 +# Remove processed options from $@ +shift 1 +REMAINING_OPTIONS=$@ + +FAIL=0 + +export VSOMEIP_CONFIGURATION=$PASSED_JSON_FILE + +# Start the services +export VSOMEIP_APPLICATION_NAME=initial_event_test_service_four +./initial_event_test_service 4 $REMAINING_OPTIONS & +PID_SERVICE_FOUR=$! + +export VSOMEIP_APPLICATION_NAME=initial_event_test_service_five +./initial_event_test_service 5 $REMAINING_OPTIONS & +PID_SERVICE_FIVE=$! + +export VSOMEIP_APPLICATION_NAME=initial_event_test_service_six +./initial_event_test_service 6 $REMAINING_OPTIONS & +PID_SERVICE_SIX=$! + +sleep 3 + +unset VSOMEIP_APPLICATION_NAME + +# Array for client pids +CLIENT_PIDS=() + +# Start first client which subscribes remotely +./initial_event_test_client 9000 DONT_EXIT $REMAINING_OPTIONS & +FIRST_PID=$! + +# remove SUBSCRIBE_ONLY_ONCE parameter from $REMAINING_OPTIONS to ensure the +# following clients subscribe normaly +REMAINING_OPTIONS=${REMAINING_OPTIONS%SUBSCRIBE_ONLY_ONE} +REMAINING_OPTIONS=${REMAINING_OPTIONS#SUBSCRIBE_ONLY_ONE} + +# Start availability checker in order to wait until the services on the remote +# were started as well +./initial_event_test_availability_checker 1234 $REMAINING_OPTIONS & +PID_AVAILABILITY_CHECKER=$! + +# wait until the services on the remote node were started as well +wait $PID_AVAILABILITY_CHECKER +sleep 2; +for client_number in $(seq 9001 9011) +do + ./initial_event_test_client $client_number STRICT_CHECKING $REMAINING_OPTIONS & + CLIENT_PIDS+=($!) +done + +# Wait until all clients are finished +for job in ${CLIENT_PIDS[*]} +do + # Fail gets incremented if a client exits with a non-zero exit code + wait $job || FAIL=$(($FAIL+1)) +done + +# wait until all clients exited on master side +./initial_event_test_stop_service SLAVE & +PID_STOP_SERVICE=$! +wait $PID_STOP_SERVICE + +# shutdown the first client +kill $FIRST_PID +wait $FIRST_PID || FAIL=$(($FAIL+1)) + +# shutdown the services +kill $PID_SERVICE_SIX +kill $PID_SERVICE_FIVE +kill $PID_SERVICE_FOUR + +sleep 1 +echo "" + +# Check if they exited successfully +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/initial_event_tests/initial_event_test_stop_service.cpp b/test/network_tests/initial_event_tests/initial_event_test_stop_service.cpp new file mode 100644 index 0000000..db91d06 --- /dev/null +++ b/test/network_tests/initial_event_tests/initial_event_test_stop_service.cpp @@ -0,0 +1,287 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "initial_event_test_globals.hpp" + + +class initial_event_test_stop_service { +public: + initial_event_test_stop_service(struct initial_event_test::service_info _service_info, bool _is_master) : + service_info_(_service_info), + is_master_(_is_master), + app_(vsomeip::runtime::get()->create_application()), + wait_until_registered_(true), + wait_until_stop_service_other_node_available_(true), + wait_until_shutdown_method_called_(true), + offer_thread_(std::bind(&initial_event_test_stop_service::run, this)), + wait_for_stop_(true), + stop_thread_(std::bind(&initial_event_test_stop_service::wait_for_stop, this)), + called_other_node_(false) { + if (!app_->init()) { + offer_thread_.detach(); + stop_thread_.detach(); + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&initial_event_test_stop_service::on_state, this, + std::placeholders::_1)); + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.method_id, + std::bind(&initial_event_test_stop_service::on_shutdown_method_called, this, + std::placeholders::_1)); + + // register availability for all other services and request their event. + if (is_master_) { + app_->request_service( + initial_event_test::stop_service_slave.service_id, + initial_event_test::stop_service_slave.instance_id); + app_->register_availability_handler( + initial_event_test::stop_service_slave.service_id, + initial_event_test::stop_service_slave.instance_id, + std::bind(&initial_event_test_stop_service::on_availability, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + } else { + app_->request_service( + initial_event_test::stop_service_master.service_id, + initial_event_test::stop_service_master.instance_id); + app_->register_availability_handler( + initial_event_test::stop_service_master.service_id, + initial_event_test::stop_service_master.instance_id, + std::bind(&initial_event_test_stop_service::on_availability, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + } + app_->start(); + } + + ~initial_event_test_stop_service() { + if (offer_thread_.joinable()) { + offer_thread_.join(); + } + if (stop_thread_.joinable()) { + stop_thread_.join(); + } + } + + void offer() { + if (is_master_) { + app_->offer_service( + initial_event_test::stop_service_master.service_id, + initial_event_test::stop_service_master.instance_id); + } else { + app_->offer_service( + initial_event_test::stop_service_slave.service_id, + initial_event_test::stop_service_slave.instance_id); + } + } + + void stop_offer() { + if (is_master_) { + app_->stop_offer_service( + initial_event_test::stop_service_master.service_id, + initial_event_test::stop_service_master.instance_id); + } else { + app_->stop_offer_service( + initial_event_test::stop_service_slave.service_id, + initial_event_test::stop_service_slave.instance_id); + } + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + bool notify(false); + if(_is_available) { + VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Service [" + << std::setw(4) << std::setfill('0') << std::hex << _service + << "." << _instance << "] is available."; + if(is_master_) { + if(_service == initial_event_test::stop_service_slave.service_id + && _instance == initial_event_test::stop_service_slave.instance_id) { + notify = true; + } + } else { + if(_service == initial_event_test::stop_service_master.service_id + && _instance == initial_event_test::stop_service_master.instance_id) { + notify = true; + } + } + } + if (notify) { + std::lock_guard its_lock(availability_mutex_); + wait_until_stop_service_other_node_available_ = false; + availability_condition_.notify_one(); + } + } + + void on_shutdown_method_called(const std::shared_ptr &_message) { + if(_message->get_message_type() == vsomeip::message_type_e::MT_REQUEST_NO_RETURN) { + VSOMEIP_DEBUG << "Received a request with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_session() << "] shutdown method called"; + + std::lock_guard its_lock(stop_mutex_); + wait_for_stop_ = false; + stop_condition_.notify_one(); + } + } + + void run() { + { + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + + { + std::unique_lock its_availability_lock(availability_mutex_); + while (wait_until_stop_service_other_node_available_) { + availability_condition_.wait(its_availability_lock); + } + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Calling shutdown method on remote side"; + + std::shared_ptr msg(vsomeip::runtime::get()->create_request()); + msg->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + if(is_master_) { + msg->set_service(initial_event_test::stop_service_slave.service_id); + msg->set_instance(initial_event_test::stop_service_slave.instance_id); + msg->set_method(initial_event_test::stop_service_slave.method_id); + } else { + msg->set_service(initial_event_test::stop_service_master.service_id); + msg->set_instance(initial_event_test::stop_service_master.instance_id); + msg->set_method(initial_event_test::stop_service_master.method_id); + } + app_->send(msg); + called_other_node_ = true; + { + std::unique_lock its_lock(mutex_); + while (wait_until_shutdown_method_called_) { + auto its_reason = condition_.wait_for(its_lock, std::chrono::milliseconds(250)); + if (its_reason == std::cv_status::timeout) { + std::lock_guard its_lock(stop_mutex_); + wait_for_stop_ = false; + stop_condition_.notify_one(); + wait_until_shutdown_method_called_ = false; + } + } + } + } + + void wait_for_stop() { + static int its_call_number(0); + its_call_number++; + + std::unique_lock its_lock(stop_mutex_); + while (wait_for_stop_) { + stop_condition_.wait(its_lock); + } + VSOMEIP_INFO << "(" << std::dec << its_call_number << ") [" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id + << "] shutdown method was called, going down"; + while(!called_other_node_) { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + // let offer thread exit + { + std::lock_guard its_lock(mutex_); + wait_until_shutdown_method_called_ = false; + condition_.notify_one(); + } + app_->clear_all_handler(); + app_->stop(); + } + +private: + initial_event_test::service_info service_info_; + bool is_master_; + std::shared_ptr app_; + std::map, bool> other_services_available_; + std::map, std::uint32_t> other_services_received_notification_; + + bool wait_until_registered_; + bool wait_until_stop_service_other_node_available_; + bool wait_until_shutdown_method_called_; + std::mutex mutex_; + std::condition_variable condition_; + std::thread offer_thread_; + + std::mutex availability_mutex_; + std::condition_variable availability_condition_; + + std::atomic wait_for_stop_; + std::mutex stop_mutex_; + std::condition_variable stop_condition_; + std::thread stop_thread_; + + std::atomic called_other_node_; +}; + +static bool is_master = false; + +TEST(someip_initial_event_test, wait_for_stop_method_to_be_called) +{ + if(is_master) { + initial_event_test_stop_service its_sample(initial_event_test::stop_service_master, is_master); + } else { + initial_event_test_stop_service its_sample(initial_event_test::stop_service_slave, is_master); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a valid type, like: " << argv[0] << " MASTER" << std::endl; + std::cerr << "Valid types are in the range of [MASTER,SLAVE]" << std::endl; + return 1; + } + + if (argc >= 2 && std::string("MASTER") == std::string(argv[1])) { + is_master = true; + } else if (argc >= 2 && std::string("SLAVE") == std::string(argv[1])){ + is_master = false; + } + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/magic_cookies_tests/conf/magic_cookies_test_client.json.in b/test/network_tests/magic_cookies_tests/conf/magic_cookies_test_client.json.in new file mode 100644 index 0000000..bcb2e29 --- /dev/null +++ b/test/network_tests/magic_cookies_tests/conf/magic_cookies_test_client.json.in @@ -0,0 +1,85 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "netmask":"255.255.255.0", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"true", + "path":"/var/log/vsomeip.log" + }, + "dlt":"true" + }, + "applications": + [ + { + "name":"magic_cookies_test_client", + "id":"0x1343" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678", + "unicast":"@TEST_IP_MASTER@", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"true" + }, + "events": + [ + { + "event":"0x0777", + "is_field":"true" + }, + { + "event":"0x0778", + "is_field":"false" + }, + { + "event":"0x0779", + "is_field":"true" + } + ], + "eventgroups": + [ + { + "eventgroup":"0x4455", + "events": + [ + "0x777", + "0x778" + ] + }, + { + "eventgroup":"0x4465", + "events": + [ + "0x778", + "0x779" + ] + }, + { + "eventgroup":"0x4555", + "events": + [ + "0x777", + "0x779" + ] + } + ] + } + ], + "routing":"magic_cookies_test_client", + "service-discovery": + { + "enable":"false", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/magic_cookies_tests/conf/magic_cookies_test_service.json.in b/test/network_tests/magic_cookies_tests/conf/magic_cookies_test_service.json.in new file mode 100644 index 0000000..0e53c24 --- /dev/null +++ b/test/network_tests/magic_cookies_tests/conf/magic_cookies_test_service.json.in @@ -0,0 +1,88 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"debug", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"magic_cookies_test_service", + "id":"0x1277" + } + ], + "services": + [ + { + "service":"0x1234", + "instance":"0x5678", + "reliable": + { + "port":"30509", + "enable-magic-cookies":"true" + }, + "events": + [ + { + "event":"0x0777", + "is_field":"false", + "is_reliable":"true", + "update-cycle":"2000" + }, + { + "event":"0x0778", + "is_field":"true", + "is_reliable":"true", + "update-cycle":"0" + }, + { + "event":"0x0779", + "is_field":"false", + "is_reliable":"true" + } + ], + "eventgroups": + [ + { + "eventgroup":"0x4455", + "events": + [ + "0x777", + "0x778" + ] + }, + { + "eventgroup":"0x4465", + "events": + [ + "0x778", + "0x779" + ] + }, + { + "eventgroup":"0x4555", + "events": + [ + "0x777", + "0x779" + ] + } + ] + } + ], + "routing":"magic_cookies_test_service", + "service-discovery": + { + "enable":"false", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/magic_cookies_tests/magic_cookies_test_client.cpp b/test/network_tests/magic_cookies_tests/magic_cookies_test_client.cpp new file mode 100644 index 0000000..89a0029 --- /dev/null +++ b/test/network_tests/magic_cookies_tests/magic_cookies_test_client.cpp @@ -0,0 +1,246 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include + +#include + +#include + +#include "../someip_test_globals.hpp" +#include "../implementation/runtime/include/application_impl.hpp" +#include "../implementation/routing/include/routing_manager.hpp" + +class magic_cookies_test_client { +public: + magic_cookies_test_client() + : app_(new vsomeip::application_impl("", "")), + is_blocked_(false), + sent_messages_good_(8), + sent_messages_bad_(7), + received_responses_(0), + received_errors_(0), + wait_for_replies_(true), + runner_(std::bind(&magic_cookies_test_client::run, this)) { + } + + void init() { + VSOMEIP_INFO << "Initializing..."; + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + exit(EXIT_FAILURE); + } + + app_->register_state_handler( + std::bind( + &magic_cookies_test_client::on_state, + this, + std::placeholders::_1)); + + app_->register_message_handler( + vsomeip::ANY_SERVICE, vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, + std::bind(&magic_cookies_test_client::on_message, + this, + std::placeholders::_1)); + + app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&magic_cookies_test_client::on_availability, + this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), + vsomeip::DEFAULT_MAJOR, vsomeip::DEFAULT_MINOR); + } + + void start() { + VSOMEIP_INFO << "Starting..."; + app_->start(); + } + + void stop() { + VSOMEIP_INFO << "Stopping..."; + app_->clear_all_handler(); + app_->stop(); + } + + void on_state(vsomeip::state_type_e _state) { + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + VSOMEIP_INFO << "Client registration done."; + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + vsomeip::ANY_MAJOR, vsomeip::ANY_MINOR); + } + } + + void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) { + VSOMEIP_INFO << "Service [" + << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance + << "] is " + << (_is_available ? "available." : "NOT available."); + + if (vsomeip_test::TEST_SERVICE_SERVICE_ID == _service && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) { + static bool is_available = false; + if (is_available && !_is_available) is_available = false; + else if (_is_available && !is_available) { + is_available = true; + std::lock_guard< std::mutex > its_lock(mutex_); + is_blocked_ = true; + condition_.notify_one(); + } + } + } + + void on_message(const std::shared_ptr< vsomeip::message > &_response) { + if (_response->get_return_code() == vsomeip::return_code_e::E_OK) { + VSOMEIP_INFO << "Received a response from Service [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() + << "." + << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() + << "] to Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() + << "/" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() + << "]"; + received_responses_++; + } else if (_response->get_return_code() == vsomeip::return_code_e::E_MALFORMED_MESSAGE) { + VSOMEIP_INFO << "Received an error message from Service [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() + << "." + << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() + << "] to Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() + << "/" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() + << "]"; + received_errors_++; + } + if (received_errors_ == sent_messages_bad_ + && received_responses_ == sent_messages_good_) { + std::lock_guard its_lock(mutex_); + wait_for_replies_ = false; + condition_.notify_one(); + } + } + + void join() { + runner_.join(); + } + + void run() { + std::unique_lock< std::mutex > its_lock(mutex_); + while (!is_blocked_) { + if (std::cv_status::timeout == + condition_.wait_for(its_lock, std::chrono::milliseconds(5000))) { + GTEST_NONFATAL_FAILURE_("Service didn't become available within 5s."); + break; + } + } + VSOMEIP_INFO << "Running..."; + + vsomeip::routing_manager *its_routing = app_->get_routing_manager(); + + vsomeip::byte_t its_good_payload_data[] = { + 0x12, 0x34, 0x84, 0x21, + 0x00, 0x00, 0x00, 0x11, + 0x13, 0x43, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 + }; + + vsomeip::byte_t its_bad_payload_data[] = { + 0x12, 0x34, 0x84, 0x21, + 0x00, 0x00, 0x01, 0x23, + 0x13, 0x43, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, + 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 + }; + + // Test sequence + its_good_payload_data[11] = 0x01; + its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_bad_payload_data[11] = 0x02; + its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_good_payload_data[11] = 0x03; + its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_bad_payload_data[11] = 0x04; + its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_bad_payload_data[11] = 0x05; + its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_good_payload_data[11] = 0x06; + its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_good_payload_data[11] = 0x07; + its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_bad_payload_data[11] = 0x08; + its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_bad_payload_data[11] = 0x09; + its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_bad_payload_data[11] = 0x0A; + its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_good_payload_data[11] = 0x0B; + its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_good_payload_data[11] = 0x0C; + its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_good_payload_data[11] = 0x0D; + its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_bad_payload_data[11] = 0x0E; + its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + std::this_thread::sleep_for(std::chrono::seconds(11)); + its_good_payload_data[11] = 0x0F; + its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true); + + while (wait_for_replies_) { + if(std::cv_status::timeout == + condition_.wait_for(its_lock, std::chrono::milliseconds(5000))) { + GTEST_NONFATAL_FAILURE_("Didn't receive all replies/errors in time"); + break; + } + } + EXPECT_EQ(sent_messages_good_, received_responses_); + EXPECT_EQ(sent_messages_bad_, received_errors_); + stop(); + } + +private: + std::shared_ptr< vsomeip::application_impl > app_; + std::mutex mutex_; + std::condition_variable condition_; + bool is_blocked_; + const std::uint32_t sent_messages_good_; + const std::uint32_t sent_messages_bad_; + std::atomic received_responses_; + std::atomic received_errors_; + bool wait_for_replies_; + std::thread runner_; +}; + +TEST(someip_magic_cookies_test, send_good_and_bad_messages) +{ + magic_cookies_test_client its_client; + its_client.init(); + its_client.start(); + its_client.join(); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + + diff --git a/test/network_tests/magic_cookies_tests/magic_cookies_test_client_start.sh b/test/network_tests/magic_cookies_tests/magic_cookies_test_client_start.sh new file mode 100755 index 0000000..45f4d3c --- /dev/null +++ b/test/network_tests/magic_cookies_tests/magic_cookies_test_client_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=magic_cookies_test_client +export VSOMEIP_CONFIGURATION=magic_cookies_test_client.json +./magic_cookies_test_client diff --git a/test/network_tests/magic_cookies_tests/magic_cookies_test_service.cpp b/test/network_tests/magic_cookies_tests/magic_cookies_test_service.cpp new file mode 100644 index 0000000..d8ac4d7 --- /dev/null +++ b/test/network_tests/magic_cookies_tests/magic_cookies_test_service.cpp @@ -0,0 +1,168 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "../someip_test_globals.hpp" + +class magic_cookies_test_service { +public: + magic_cookies_test_service(bool _use_static_routing) : + app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + use_static_routing_(_use_static_routing), + blocked_(false), + offer_thread_(std::bind(&magic_cookies_test_service::run, this)) { + } + + ~magic_cookies_test_service() { + offer_thread_.join(); + } + void init() { + std::lock_guard its_lock(mutex_); + + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + exit(EXIT_FAILURE); + } + app_->register_message_handler( + vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + vsomeip_test::TEST_SERVICE_METHOD_ID, + std::bind(&magic_cookies_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&magic_cookies_test_service::on_state, this, + std::placeholders::_1)); + + VSOMEIP_INFO<< "Static routing " << (use_static_routing_ ? "ON" : "OFF"); + } + + void start() { + app_->start(); + } + + void offer() { + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); + } + + void stop_offer() { + app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + if (!is_registered_) { + is_registered_ = true; + std::lock_guard its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); + } + } else { + is_registered_ = false; + } + } + + void on_message(const std::shared_ptr &_request) { + VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _request->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _request->get_session() << "]"; + + std::shared_ptr its_response = vsomeip::runtime::get() + ->create_response(_request); + + std::shared_ptr its_payload = vsomeip::runtime::get() + ->create_payload(); + std::vector its_payload_data; + for (std::size_t i = 0; i < 120; ++i) + its_payload_data.push_back(static_cast(i % 256)); + its_payload->set_data(its_payload_data); + its_response->set_payload(its_payload); + + app_->send(its_response); + if(_request->get_session() == 0x0F) { + std::lock_guard its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); + } + } + + void run() { + std::unique_lock its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); + + bool is_offer(true); + blocked_ = false; + + if (use_static_routing_) { + offer(); + while (!blocked_) { + if(std::cv_status::timeout == + condition_.wait_for(its_lock, std::chrono::seconds(200))) { + GTEST_NONFATAL_FAILURE_("Didn't receive all requests within time"); + break; + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + app_->clear_all_handler(); + app_->stop(); + } else { + while (true) { + if (is_offer) + offer(); + else + stop_offer(); + std::this_thread::sleep_for(std::chrono::milliseconds(10000)); + is_offer = !is_offer; + } + } + } + +private: + std::shared_ptr app_; + bool is_registered_; + bool use_static_routing_; + + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + std::thread offer_thread_; +}; + +static bool use_static_routing = false; + +TEST(someip_magic_cookies_test, reply_to_good_messages) +{ + magic_cookies_test_service its_sample(use_static_routing); + its_sample.init(); + its_sample.start(); +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + std::string static_routing_enable("--static-routing"); + for (int i = 1; i < argc; i++) { + if (static_routing_enable == argv[i]) { + use_static_routing = true; + } + } + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/magic_cookies_tests/magic_cookies_test_service_start.sh b/test/network_tests/magic_cookies_tests/magic_cookies_test_service_start.sh new file mode 100755 index 0000000..9288b7e --- /dev/null +++ b/test/network_tests/magic_cookies_tests/magic_cookies_test_service_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=magic_cookies_test_service +export VSOMEIP_CONFIGURATION=magic_cookies_test_service.json +./magic_cookies_test_service --tcp --static-routing diff --git a/test/network_tests/magic_cookies_tests/magic_cookies_test_starter.sh b/test/network_tests/magic_cookies_tests/magic_cookies_test_starter.sh new file mode 100755 index 0000000..1e9cfc4 --- /dev/null +++ b/test/network_tests/magic_cookies_tests/magic_cookies_test_starter.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit successfully. + +# Display a message to show the user that he must now call the external service +# to finish the test successfully + +FAIL=0 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting magic cookies test on slave LXC" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./magic_cookies_test_client_start.sh\"" & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./magic_cookies_test_client_start.sh" & +else +cat < +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include "../../implementation/utility/include/byteorder.hpp" +#include "../../implementation/message/include/deserializer.hpp" +#include "../../implementation/service_discovery/include/service_discovery.hpp" +#include "../../implementation/service_discovery/include/message_impl.hpp" +#include "../../implementation/service_discovery/include/constants.hpp" +#include "../../implementation/service_discovery/include/enumeration_types.hpp" +#include "../../implementation/service_discovery/include/eventgroupentry_impl.hpp" +#include "../../implementation/service_discovery/include/serviceentry_impl.hpp" +#include "../../implementation/message/include/message_impl.hpp" +#include "../../implementation/service_discovery/include/option_impl.hpp" +#include "../../implementation/service_discovery/include/ipv4_option_impl.hpp" +#include "malicious_data_test_globals.hpp" + +static char* remote_address; +static char* local_address; + +class malicious_data : public ::testing::Test { +public: + malicious_data() : + work_(std::make_shared(io_)), + io_thread_(std::bind(&malicious_data::io_run, this)) {} +protected: + + void TearDown() { + work_.reset(); + io_thread_.join(); + io_.stop(); + } + + void io_run() { + io_.run(); + } + + boost::asio::io_context io_; + std::shared_ptr work_; + std::thread io_thread_; +}; + +TEST_F(malicious_data, send_malicious_events) +{ + std::promise client_subscribed; + + boost::asio::ip::tcp::socket tcp_socket(io_); + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + + std::thread receive_thread([&](){ + std::atomic keep_receiving(true); + std::function receive; + std::vector receive_buffer(4096); + std::vector its_received_events; + + const std::function receive_cbk = [&]( + const boost::system::error_code& error, std::size_t bytes_transferred) { + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + return; + } + #if 0 + std::stringstream str; + for (size_t i = 0; i < bytes_transferred; i++) { + str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; + } + std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; + #endif + + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], + receive_buffer[VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], + receive_buffer[VSOMEIP_METHOD_POS_MAX]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(1u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); + EXPECT_EQ(1,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(1u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); + } + client_subscribed.set_value(true); + keep_receiving = false; + } + } + } + + + }; + + receive = [&]() { + udp_socket.async_receive(boost::asio::buffer(receive_buffer, receive_buffer.capacity()), + receive_cbk); + }; + + receive(); + while(keep_receiving) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + }); + + std::thread send_thread([&]() { + try { + std::promise client_connected; + boost::asio::ip::tcp::socket::endpoint_type local( + boost::asio::ip::address::from_string(std::string(local_address)), + 40001); + boost::asio::ip::tcp::acceptor its_acceptor(io_); + boost::system::error_code ec; + its_acceptor.open(local.protocol(), ec); + boost::asio::detail::throw_error(ec, "acceptor open"); + its_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "acceptor set_option"); + its_acceptor.bind(local, ec); + boost::asio::detail::throw_error(ec, "acceptor bind"); + its_acceptor.listen(boost::asio::socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec, "acceptor listen"); + its_acceptor.async_accept(tcp_socket, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); + client_connected.set_value(true); + } else { + ADD_FAILURE() << "accept_cbk: " << _error.message(); + } + }); + + + // offer the service + std::uint8_t its_offer_service_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x01, 0x00, 0x00, 0x20, + 0x33, 0x44, 0x00, 0x01, // service / instance + 0x00, 0xff, 0xff, 0xff, // major / ttl + 0x00, 0x00, 0x00, 0x00, // minor + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // slave address + 0x00, 0x06, 0x9c, 0x41, + }; + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); + + // wait until client established TCP connection + if (std::future_status::timeout == client_connected.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't connect within time"; + } + + // wait until client subscribed + if (std::future_status::timeout == client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't subscribe within time"; + } + + // send malicious data as server + std::uint8_t its_malicious_data[] = { + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x11, 0x3f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x38, 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x5f, 0x5f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x86, 0x6f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xad, 0x7f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xd4, 0x8f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xfb, 0x9f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x22, 0xaf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, // payload missing + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0xbf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x70, 0xcf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x43, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x6d, 0x80, 0x00, 0x45, 0x22, 0x80, 0x00, 0x45, 0x3b, 0x80, 0x00, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x97, 0xdf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x23, 0x99, 0x00, 0x4e, 0xb3, 0xe4, 0x4e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x48, 0x00, 0x00, 0x45, 0x96, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x45, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x22, 0x91, 0x00, 0x4e, 0xb3, 0xe3, 0xd7, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x44, 0x48, 0x00, 0x00, 0x45, 0x9c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xe5, 0xff, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x21, 0x6c, 0x00, 0x4e, 0xb3, 0xe3, 0x55, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x20, 0x00, 0x44, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0d, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x20, 0xa9, 0x00, 0x4e, 0xb3, 0xe3, 0x56, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x45, 0x6d, 0x80, 0x00, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x34, 0x1f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1f, 0xc6, 0x00, 0x4e, 0xb3, 0xe3, 0x87, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x96, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x44, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x5b, 0x2f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1e, 0xf1, 0x00, 0x4e, 0xb3, 0xe3, 0x5e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x45, 0x9c, 0x40, 0x00, 0x45, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x82, 0x3f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xad, 0x00, 0x4e, 0xb3, 0xe3, 0xa8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x48, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x44, 0xaf, 0x00, 0x00, 0x45, 0x3b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xa9, 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xec, 0x00, 0x4e, 0xb3, 0xe3, 0xd8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa8, 0xc0, 0x00, 0x44, 0xaf, 0x00, 0x00, 0x45, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xd0, 0x5f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfa, 0x00, 0x00, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xf7, 0x6f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x19, 0x20, 0x00, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x44, 0x80, 0x02, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1e, 0x7f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x09, 0x80, 0x00, 0x44, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + tcp_socket.send(boost::asio::buffer(its_malicious_data)); + + // establish second tcp connection as client and send malicious data as well + boost::asio::ip::tcp::socket tcp_socket2(io_); + boost::asio::ip::tcp::socket::endpoint_type remote( + boost::asio::ip::address::from_string(std::string(remote_address)), + 40001); + tcp_socket2.open(remote.protocol()); + tcp_socket2.connect(remote); + std::uint8_t its_malicious_client_data[] = { + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x11, 0x3f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x38, 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x5f, 0x5f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x86, 0x6f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xad, 0x7f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xd4, 0x8f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0xfb, 0x9f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x22, 0xaf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, // payload missing + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x49, 0xbf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x24, 0x02, 0x00, 0x4e, 0xb3, 0xe4, 0x7a, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x70, 0xcf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x43, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x6d, 0x80, 0x00, 0x45, 0x22, 0x80, 0x00, 0x45, 0x3b, 0x80, 0x00, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x97, 0xdf, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x23, 0x99, 0x00, 0x4e, 0xb3, 0xe4, 0x4e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x48, 0x00, 0x00, 0x45, 0x96, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x45, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xbe, 0xef, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x22, 0x91, 0x00, 0x4e, 0xb3, 0xe3, 0xd7, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x44, 0x48, 0x00, 0x00, 0x45, 0x9c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xe5, 0xff, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x21, 0x6c, 0x00, 0x4e, 0xb3, 0xe3, 0x55, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x20, 0x00, 0x44, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x0d, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x20, 0xa9, 0x00, 0x4e, 0xb3, 0xe3, 0x56, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x45, 0x6d, 0x80, 0x00, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x34, 0x1f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1f, 0xc6, 0x00, 0x4e, 0xb3, 0xe3, 0x87, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x96, 0x00, 0x00, 0x45, 0x83, 0x40, 0x00, 0x44, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x5b, 0x2f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1e, 0xf1, 0x00, 0x4e, 0xb3, 0xe3, 0x5e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x45, 0x9c, 0x40, 0x00, 0x45, 0x22, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x82, 0x3f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xad, 0x00, 0x4e, 0xb3, 0xe3, 0xa8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x48, 0x00, 0x00, 0x45, 0x16, 0x00, 0x00, 0x44, 0xaf, 0x00, 0x00, 0x45, 0x3b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xa9, 0x4f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xec, 0x00, 0x4e, 0xb3, 0xe3, 0xd8, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa8, 0xc0, 0x00, 0x44, 0xaf, 0x00, 0x00, 0x45, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xd0, 0x5f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfa, 0x00, 0x00, 0x44, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0xf7, 0x6f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x19, 0x20, 0x00, 0x43, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x33, 0x45, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1e, 0x7f, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x03, 0x05, 0x26, 0x5c, 0x00, 0x04, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x0e, 0x47, 0x36, 0x37, 0x38, 0x35, 0x37, 0x35, 0x00, 0x4d, 0xd5, 0x1d, 0xf9, 0x00, 0x4e, 0xb3, 0xe3, 0xdd, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x09, 0x80, 0x00, 0x44, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + tcp_socket2.send(boost::asio::buffer(its_malicious_client_data)); + + std::this_thread::sleep_for(std::chrono::milliseconds(1500)); + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x33, 0x45, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); + } catch (const std::exception& _e) { + ADD_FAILURE() << "catched exception: " << _e.what(); + } + + }); + + send_thread.join(); + receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); + tcp_socket.close(ec); + +} + +/* + * @test Send a message with an invalid protocol version to the test master + * two times as client and two time as service. Ensure that message with the + * WRONG_PROTOCOL_VERSION is sent back in both cases and that the client + * reestablishes the TCP connection after the service sent an message with an + * invalid protocol version back + */ +TEST_F(malicious_data, send_wrong_protocol_version) +{ + std::promise remote_client_subscribed; + std::promise offer_received; + + boost::asio::ip::tcp::socket tcp_socket(io_); + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + + std::thread sd_receive_thread([&](){ + std::atomic keep_receiving(true); + std::vector receive_buffer(4096); + std::vector its_received_events; + std::atomic service_offered(false); + std::atomic client_subscribed(false); + + // join the sd multicast group 224.0.24.1 + udp_socket.set_option(boost::asio::ip::multicast::join_group( + boost::asio::ip::address::from_string("224.0.24.1").to_v4())); + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + return; + } else { + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], + receive_buffer[VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], + receive_buffer[VSOMEIP_METHOD_POS_MAX]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(1u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); + EXPECT_EQ(1,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(1u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); + } + remote_client_subscribed.set_value(); + client_subscribed = true; + } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { + EXPECT_TRUE(e->is_service_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); + EXPECT_EQ(2,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id + 1u, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(2u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_EQ(0u, its_casted_entry->get_minor_version()); + } + offer_received.set_value(); + service_offered = true; + } + } + if (service_offered && client_subscribed) { + keep_receiving = false; + } + } else { + ADD_FAILURE() << " received non-sd message"; + } + } + } + }); + + std::thread send_thread([&]() { + try { + std::promise client_connected; + boost::asio::ip::tcp::socket::endpoint_type local( + boost::asio::ip::address::from_string(std::string(local_address)), + 40001); + boost::asio::ip::tcp::acceptor its_acceptor(io_); + boost::system::error_code ec; + its_acceptor.open(local.protocol(), ec); + boost::asio::detail::throw_error(ec, "acceptor open"); + its_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "acceptor set_option"); + its_acceptor.bind(local, ec); + boost::asio::detail::throw_error(ec, "acceptor bind"); + its_acceptor.listen(boost::asio::socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec, "acceptor listen"); + its_acceptor.async_accept(tcp_socket, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); + client_connected.set_value(); + } else { + ADD_FAILURE() << "accept_cbk: " << _error.message(); + } + }); + + + // offer the service + std::uint8_t its_offer_service_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x01, 0x00, 0x00, 0x20, + 0x33, 0x44, 0x00, 0x01, // service / instance + 0x00, 0xff, 0xff, 0xff, // major / ttl + 0x00, 0x00, 0x00, 0x00, // minor + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // slave address + 0x00, 0x06, 0x9c, 0x41, + }; + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); + + // wait until client established TCP connection + if (std::future_status::timeout == client_connected.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't connect within time"; + } + + // wait until client subscribed + if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't subscribe within time"; + } + + // wait until a offer was received + if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive offer within time"; + } + + std::atomic fin_as_service_received(0); + std::promise client_reconnected1; + + std::thread tcp_receive_thread([&]() { + std::atomic keep_receiving(true); + std::vector receive_buffer(4096); + + while (keep_receiving) { + boost::system::error_code error; + tcp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error == boost::asio::error::eof) { + EXPECT_EQ(boost::asio::error::eof, error); + fin_as_service_received++; + keep_receiving = false; + } else { + keep_receiving = false; + ADD_FAILURE() << __func__ << ":" << __LINE__ << " error: " << error.message(); + return; + } + } + }); + + boost::asio::ip::tcp::socket tcp_socket3(io_); + its_acceptor.async_accept(tcp_socket3, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket3.set_option(boost::asio::ip::tcp::no_delay(true)); + client_reconnected1.set_value(); + } else { + ADD_FAILURE() << "accept_cbk2: " << _error.message(); + } + }); + // send malicious data as server (too long length and wrong protocol version) + std::uint8_t its_malicious_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x07, 0x7f, + 0xBB, 0xBB, 0xCA, 0xFE, + 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA + }; + tcp_socket.send(boost::asio::buffer(its_malicious_data)); + + // wait until client reestablished TCP connection + if (std::future_status::timeout == client_reconnected1.get_future().wait_for(std::chrono::seconds(10))) { + tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket3.close(ec); + ADD_FAILURE() << "Client didn't reconnect within time 1"; + } + + tcp_receive_thread.join(); + + EXPECT_EQ(1u, fin_as_service_received); + + std::thread tcp_receive_thread2([&]() { + std::atomic keep_receiving(true); + std::vector receive_buffer(4096); + while (keep_receiving) { + boost::system::error_code error; + tcp_socket3.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error == boost::asio::error::eof) { + EXPECT_EQ(boost::asio::error::eof, error); + fin_as_service_received++; + // client must sent back error response before closing the connection + EXPECT_EQ(2u, fin_as_service_received); + if (fin_as_service_received == 2) { + keep_receiving = false; + } + } else { + keep_receiving = false; + return; + } + } + }); + + // send malicious data as server (wrong protocol version) + std::uint8_t its_malicious_data_correct_length[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xBB, 0xBB, 0xCA, 0xFE, + 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA + }; + tcp_socket3.send(boost::asio::buffer(its_malicious_data_correct_length)); + + tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket3.close(ec); + + + tcp_receive_thread2.join(); + EXPECT_EQ(2u, fin_as_service_received); + + // establish second tcp connection as client and send malicious data as well + std::atomic error_response_as_client_received(0); + std::atomic fin_as_client_received(0); + + boost::asio::ip::tcp::socket tcp_socket2(io_); + boost::asio::ip::tcp::socket::endpoint_type remote( + boost::asio::ip::address::from_string(std::string(remote_address)), + 40001); + tcp_socket2.open(remote.protocol()); + tcp_socket2.connect(remote); + + + std::thread tcp_service_receive_thread([&]() { + std::atomic keep_receiving(true); + std::vector receive_buffer(4096); + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = tcp_socket2.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (!error) { + #if 0 + std::stringstream str; + for (size_t i = 0; i < bytes_transferred; i++) { + str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; + } + std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; + #endif + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + std::shared_ptr its_message(its_deserializer.deserialize_message()); + EXPECT_EQ(0x3345, its_message->get_service()); + EXPECT_EQ(0x1, its_message->get_method()); + EXPECT_EQ(0xCCCC, its_message->get_client()); + EXPECT_EQ(0xDDDD, its_message->get_session()); + EXPECT_EQ(vsomeip::return_code_e::E_WRONG_PROTOCOL_VERSION, its_message->get_return_code()); + EXPECT_EQ(vsomeip::message_type_e::MT_ERROR, its_message->get_message_type()); + error_response_as_client_received++; + // service must sent back error response before closing the connection + EXPECT_EQ(error_response_as_client_received - 1u, fin_as_client_received); + } else { + EXPECT_EQ(boost::asio::error::eof, error); + fin_as_client_received++; + // service must sent back error response before closing the connection + EXPECT_EQ(error_response_as_client_received, fin_as_client_received); + if (fin_as_client_received == 1) { + keep_receiving = false; + } + } + } + }); + + // send malicious data as client (too long length and wrong protocol version) + std::uint8_t its_malicious_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x07, 0x7f, + 0xCC, 0xCC, 0xDD, 0xDD, + 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA + }; + tcp_socket2.send(boost::asio::buffer(its_malicious_client_data)); + tcp_service_receive_thread.join(); + EXPECT_EQ(1u, error_response_as_client_received); + EXPECT_EQ(1u, fin_as_client_received); + + tcp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket2.close(ec); + + // establish a tcp connection as client again and send wrong protocol + // version in message with a correct length field + boost::asio::ip::tcp::socket tcp_socket5(io_); + tcp_socket5.open(remote.protocol()); + tcp_socket5.connect(remote); + + std::thread tcp_service_receive_thread2([&]() { + std::atomic keep_receiving(true); + std::vector receive_buffer(4096); + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = tcp_socket5.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (!error) { + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + std::shared_ptr its_message(its_deserializer.deserialize_message()); + EXPECT_EQ(0x3345, its_message->get_service()); + EXPECT_EQ(0x1, its_message->get_method()); + EXPECT_EQ(0xCCCC, its_message->get_client()); + EXPECT_EQ(0xDDDD, its_message->get_session()); + EXPECT_EQ(vsomeip::return_code_e::E_WRONG_PROTOCOL_VERSION, its_message->get_return_code()); + EXPECT_EQ(vsomeip::message_type_e::MT_ERROR, its_message->get_message_type()); + error_response_as_client_received++; + // service must sent back error response before closing the connection + EXPECT_EQ(error_response_as_client_received - 1u, fin_as_client_received); + if (error_response_as_client_received == 2) { + keep_receiving = false; + } + } + } + }); + + // send malicious data as client (wrong protocol version) + std::uint8_t its_malicious_client_data_correct_length[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xCC, 0xCC, 0xDD, 0xDD, + 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA + }; + tcp_socket5.send(boost::asio::buffer(its_malicious_client_data_correct_length)); + tcp_service_receive_thread2.join(); + EXPECT_EQ(2u, error_response_as_client_received); + EXPECT_EQ(1u, fin_as_client_received); + + tcp_socket5.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket5.close(ec); + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x33, 0x45, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); + udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); + udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket2.close(ec); + } catch (const std::exception& _e) { + ADD_FAILURE() << "catched exception: " << _e.what(); + } + + }); + + send_thread.join(); + sd_receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); + tcp_socket.close(ec); + +} + +/* + * @test Send a message with an invalid message type to the test master + * one time as client and one time as service. Ensure that the client + * reestablishes the TCP connection after the service sent an message with an + * invalid protocol version back + */ +TEST_F(malicious_data, send_wrong_message_type) +{ + std::promise remote_client_subscribed; + std::promise offer_received; + + boost::asio::ip::tcp::socket tcp_socket(io_); + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + + std::thread sd_receive_thread([&](){ + std::atomic keep_receiving(true); + std::vector receive_buffer(4096); + std::vector its_received_events; + std::atomic service_offered(false); + std::atomic client_subscribed(false); + + // join the sd multicast group 224.0.24.1 + udp_socket.set_option(boost::asio::ip::multicast::join_group( + boost::asio::ip::address::from_string("224.0.24.1").to_v4())); + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + return; + } else { + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], + receive_buffer[VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], + receive_buffer[VSOMEIP_METHOD_POS_MAX]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(1u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); + EXPECT_EQ(1,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(1u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); + } + remote_client_subscribed.set_value(); + client_subscribed = true; + } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { + EXPECT_TRUE(e->is_service_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); + EXPECT_EQ(2,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id + 1u, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(2u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_EQ(0u, its_casted_entry->get_minor_version()); + } + offer_received.set_value(); + service_offered = true; + } + } + if (service_offered && client_subscribed) { + keep_receiving = false; + } + } else { + ADD_FAILURE() << " received non-sd message"; + } + } + } + }); + + std::thread send_thread([&]() { + try { + std::promise client_connected; + boost::asio::ip::tcp::socket::endpoint_type local( + boost::asio::ip::address::from_string(std::string(local_address)), + 40001); + boost::asio::ip::tcp::acceptor its_acceptor(io_); + boost::system::error_code ec; + its_acceptor.open(local.protocol(), ec); + boost::asio::detail::throw_error(ec, "acceptor open"); + its_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "acceptor set_option"); + its_acceptor.bind(local, ec); + boost::asio::detail::throw_error(ec, "acceptor bind"); + its_acceptor.listen(boost::asio::socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec, "acceptor listen"); + its_acceptor.async_accept(tcp_socket, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); + client_connected.set_value(); + } else { + ADD_FAILURE() << "accept_cbk: " << _error.message(); + } + }); + + + // offer the service + std::uint8_t its_offer_service_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x01, 0x00, 0x00, 0x20, + 0x33, 0x44, 0x00, 0x01, // service / instance + 0x00, 0xff, 0xff, 0xff, // major / ttl + 0x00, 0x00, 0x00, 0x00, // minor + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // slave address + 0x00, 0x06, 0x9c, 0x41, + }; + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); + + // wait until client established TCP connection + if (std::future_status::timeout == client_connected.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't connect within time"; + } + + // wait until client subscribed + if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't subscribe within time"; + } + + // wait until a offer was received + if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive offer within time"; + } + + std::atomic fin_as_service_received(false); + std::promise client_reconnected; + + std::thread tcp_receive_thread([&]() { + std::atomic keep_receiving(true); + std::vector receive_buffer(4096); + + while (keep_receiving) { + boost::system::error_code error; + tcp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (!error) { + ADD_FAILURE() << __func__ << ":" << __LINE__ + << " received a non-error:" << error.message(); + } else if (error == boost::asio::error::eof) { + EXPECT_EQ(boost::asio::error::eof, error); + fin_as_service_received = true; + keep_receiving = false; + } else { + keep_receiving = false; + ADD_FAILURE() << __func__ << ":" << __LINE__ << " error: " << error.message(); + return; + } + } + }); + + boost::asio::ip::tcp::socket tcp_socket3(io_); + its_acceptor.async_accept(tcp_socket3, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); + client_reconnected.set_value(); + } else { + ADD_FAILURE() << "accept_cbk2: " << _error.message(); + } + }); + // send malicious data as server (too long length and wrong message type) + std::uint8_t its_malicious_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x07, 0x7f, + 0xBB, 0xBB, 0xCA, 0xFE, + 0x01, 0x00, 0xAA, 0x00 // message type set to 0xAA + }; + tcp_socket.send(boost::asio::buffer(its_malicious_data)); + + // wait until client reestablished TCP connection + if (std::future_status::timeout == client_reconnected.get_future().wait_for(std::chrono::seconds(10))) { + tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket3.close(ec); + ADD_FAILURE() << "Client didn't reconnect within time"; + } else { + tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket3.close(ec); + } + + tcp_receive_thread.join(); + + EXPECT_TRUE(fin_as_service_received); + + + // establish second tcp connection as client and send malicious data as well + std::atomic fin_as_client_received(false); + + boost::asio::ip::tcp::socket tcp_socket2(io_); + boost::asio::ip::tcp::socket::endpoint_type remote( + boost::asio::ip::address::from_string(std::string(remote_address)), + 40001); + tcp_socket2.open(remote.protocol()); + tcp_socket2.connect(remote); + + + std::thread tcp_service_receive_thread([&]() { + std::atomic keep_receiving(true); + std::function receive; + std::vector receive_buffer(4096); + + auto receive_cbk = [&](const boost::system::error_code& _error, + std::size_t bytes_transferred) { + (void)bytes_transferred; + if (!_error) { + ADD_FAILURE() << __func__ << ":" << __LINE__ + << " received a non-error:" << _error.message(); + } else { + EXPECT_EQ(boost::asio::error::eof, _error); + fin_as_client_received = true; + keep_receiving = false; + + } + }; + + receive = [&]() { + tcp_socket2.async_receive(boost::asio::buffer(receive_buffer, receive_buffer.capacity()), + receive_cbk); + }; + + while (keep_receiving) { + receive(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + }); + + // send malicious data as client (too long length and wrong message type) + std::uint8_t its_malicious_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x07, 0x7f, + 0xCC, 0xCC, 0xDD, 0xDD, + 0x01, 0x00, 0xAA, 0x00 // protocol version set to 0xAA + }; + tcp_socket2.send(boost::asio::buffer(its_malicious_client_data)); + tcp_service_receive_thread.join(); + EXPECT_TRUE(fin_as_client_received); + + tcp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket2.close(ec); + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x33, 0x45, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); + udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); + udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket2.close(ec); + } catch (const std::exception& _e) { + ADD_FAILURE() << "catched exception: " << _e.what(); + } + + }); + + send_thread.join(); + sd_receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); + tcp_socket.close(ec); + +} + +/* + * @test Send a message with an invalid return code to the test master + * one time as client and one time as service. Ensure that the client + * reestablishes the TCP connection after the service sent an message with an + * invalid protocol version back + */ +TEST_F(malicious_data, send_wrong_return_code) +{ + std::promise remote_client_subscribed; + std::promise offer_received; + + boost::asio::ip::tcp::socket tcp_socket(io_); + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + + std::thread sd_receive_thread([&](){ + std::atomic keep_receiving(true); + std::vector receive_buffer(4096); + std::vector its_received_events; + std::atomic service_offered(false); + std::atomic client_subscribed(false); + + // join the sd multicast group 224.0.24.1 + udp_socket.set_option(boost::asio::ip::multicast::join_group( + boost::asio::ip::address::from_string("224.0.24.1").to_v4())); + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + return; + } else { + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], + receive_buffer[VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], + receive_buffer[VSOMEIP_METHOD_POS_MAX]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(1u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); + EXPECT_EQ(1,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(1u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); + } + remote_client_subscribed.set_value(); + client_subscribed = true; + } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { + EXPECT_TRUE(e->is_service_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); + EXPECT_EQ(2,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id + 1u, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(2u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_EQ(0u, its_casted_entry->get_minor_version()); + } + offer_received.set_value(); + service_offered = true; + } + } + if (service_offered && client_subscribed) { + keep_receiving = false; + } + } else { + ADD_FAILURE() << " received non-sd message"; + } + } + } + }); + + std::thread send_thread([&]() { + try { + std::promise client_connected; + boost::asio::ip::tcp::socket::endpoint_type local( + boost::asio::ip::address::from_string(std::string(local_address)), + 40001); + boost::asio::ip::tcp::acceptor its_acceptor(io_); + boost::system::error_code ec; + its_acceptor.open(local.protocol(), ec); + boost::asio::detail::throw_error(ec, "acceptor open"); + its_acceptor.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "acceptor set_option"); + its_acceptor.bind(local, ec); + boost::asio::detail::throw_error(ec, "acceptor bind"); + its_acceptor.listen(boost::asio::socket_base::max_connections, ec); + boost::asio::detail::throw_error(ec, "acceptor listen"); + its_acceptor.async_accept(tcp_socket, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); + client_connected.set_value(); + } else { + ADD_FAILURE() << "accept_cbk: " << _error.message(); + } + }); + + + // offer the service + std::uint8_t its_offer_service_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x01, 0x00, 0x00, 0x20, + 0x33, 0x44, 0x00, 0x01, // service / instance + 0x00, 0xff, 0xff, 0xff, // major / ttl + 0x00, 0x00, 0x00, 0x00, // minor + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // slave address + 0x00, 0x06, 0x9c, 0x41, + }; + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); + + // wait until client established TCP connection + if (std::future_status::timeout == client_connected.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't connect within time"; + } + + // wait until client subscribed + if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't subscribe within time"; + } + + // wait until a offer was received + if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive offer within time"; + } + + std::atomic fin_as_service_received(false); + std::promise client_reconnected; + + std::thread tcp_receive_thread([&]() { + std::atomic keep_receiving(true); + std::vector receive_buffer(4096); + + while (keep_receiving) { + boost::system::error_code error; + tcp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (!error) { + ADD_FAILURE() << __func__ << ":" << __LINE__ + << " received a non-error:" << error.message(); + } else if (error == boost::asio::error::eof) { + EXPECT_EQ(boost::asio::error::eof, error); + fin_as_service_received = true; + keep_receiving = false; + } else { + keep_receiving = false; + ADD_FAILURE() << __func__ << ":" << __LINE__ << " error: " << error.message(); + return; + } + } + }); + + boost::asio::ip::tcp::socket tcp_socket3(io_); + its_acceptor.async_accept(tcp_socket3, [&](boost::system::error_code _error) { + if (!_error) { + // Nagle algorithm off + tcp_socket.set_option(boost::asio::ip::tcp::no_delay(true)); + client_reconnected.set_value(); + } else { + ADD_FAILURE() << "accept_cbk2: " << _error.message(); + } + }); + // send malicious data as server (too long length and wrong return code) + std::uint8_t its_malicious_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x07, 0x7f, + 0xBB, 0xBB, 0xCA, 0xFE, + 0x01, 0x00, 0x00, 0xAA // return code set to 0xAA + }; + tcp_socket.send(boost::asio::buffer(its_malicious_data)); + + // wait until client reestablished TCP connection + if (std::future_status::timeout == client_reconnected.get_future().wait_for(std::chrono::seconds(10))) { + tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket3.close(ec); + ADD_FAILURE() << "Client didn't reconnect within time"; + } else { + tcp_socket3.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket3.close(ec); + } + + tcp_receive_thread.join(); + + EXPECT_TRUE(fin_as_service_received); + + + // establish second tcp connection as client and send malicious data as well + std::atomic fin_as_client_received(false); + + boost::asio::ip::tcp::socket tcp_socket2(io_); + boost::asio::ip::tcp::socket::endpoint_type remote( + boost::asio::ip::address::from_string(std::string(remote_address)), + 40001); + tcp_socket2.open(remote.protocol()); + tcp_socket2.connect(remote); + + + std::thread tcp_service_receive_thread([&]() { + std::atomic keep_receiving(true); + std::function receive; + std::vector receive_buffer(4096); + + auto receive_cbk = [&](const boost::system::error_code& _error, + std::size_t bytes_transferred) { + (void)bytes_transferred; + if (!_error) { + ADD_FAILURE() << __func__ << ":" << __LINE__ + << " received a non-error:" << _error.message(); + } else { + EXPECT_EQ(boost::asio::error::eof, _error); + fin_as_client_received = true; + keep_receiving = false; + + } + }; + + receive = [&]() { + tcp_socket2.async_receive(boost::asio::buffer(receive_buffer, receive_buffer.capacity()), + receive_cbk); + }; + + while (keep_receiving) { + receive(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + }); + + // send malicious data as client (too long length and wrong return code) + std::uint8_t its_malicious_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x07, 0x7f, + 0xCC, 0xCC, 0xDD, 0xDD, + 0x01, 0x00, 0x00, 0xAA // return version set to 0xAA + }; + tcp_socket2.send(boost::asio::buffer(its_malicious_client_data)); + tcp_service_receive_thread.join(); + EXPECT_TRUE(fin_as_client_received); + + tcp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket2.close(ec); + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x33, 0x45, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); + udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); + udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket2.close(ec); + } catch (const std::exception& _e) { + ADD_FAILURE() << "catched exception: " << _e.what(); + } + + }); + + send_thread.join(); + sd_receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); + tcp_socket.close(ec); + +} + +/* + * @test Send a message with an invalid protocol version, invalid message type + * and invalid return code via UDP to the test master + * one time as client and one time as service. Ensure that message with the + * WRONG_PROTOCOL_VERSION is sent back in both cases + */ +TEST_F(malicious_data, wrong_header_fields_udp) +{ + std::promise remote_client_subscribed; + std::promise offer_received; + + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + boost::asio::ip::udp::socket udp_socket_service(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 40001)); + + boost::asio::ip::udp::endpoint udp_client_info; + boost::asio::ip::udp::endpoint udp_service_info; + + + std::thread sd_receive_thread([&](){ + std::atomic keep_receiving(true); + std::vector receive_buffer(4096); + std::vector its_received_events; + std::atomic service_offered(false); + std::atomic client_subscribed(false); + + // join the sd multicast group 224.0.24.1 + udp_socket.set_option(boost::asio::ip::multicast::join_group( + boost::asio::ip::address::from_string("224.0.24.1").to_v4())); + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + return; + } else { + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], + receive_buffer[VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], + receive_buffer[VSOMEIP_METHOD_POS_MAX]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(1u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); + EXPECT_EQ(1,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(1u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_EQ(1u, its_casted_entry->get_eventgroup()); + } + std::shared_ptr op = sd_msg.get_options().front(); + EXPECT_EQ(op->get_type(), vsomeip::sd::option_type_e::IP4_ENDPOINT); + EXPECT_EQ(op->get_length(), 9u); + if (op->get_type() == vsomeip::sd::option_type_e::IP4_ENDPOINT) { + std::shared_ptr ip_op + = std::static_pointer_cast(op); + EXPECT_EQ(vsomeip::sd::layer_four_protocol_e::UDP, ip_op->get_layer_four_protocol()); + udp_client_info = boost::asio::ip::udp::endpoint( + boost::asio::ip::address_v4(ip_op->get_address()), + ip_op->get_port()); + } + + remote_client_subscribed.set_value(); + client_subscribed = true; + } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { + EXPECT_TRUE(e->is_service_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); + EXPECT_EQ(2,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(malicious_data_test::service.service_id + 1u, e->get_service()); + EXPECT_EQ(malicious_data_test::service.instance_id, e->get_instance()); + EXPECT_EQ(2u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_EQ(0u, its_casted_entry->get_minor_version()); + } + for (const auto& op : sd_msg.get_options()) { + EXPECT_EQ(op->get_type(), vsomeip::sd::option_type_e::IP4_ENDPOINT); + EXPECT_EQ(op->get_length(), 9u); + if (op->get_type() == vsomeip::sd::option_type_e::IP4_ENDPOINT) { + std::shared_ptr ip_op + = std::static_pointer_cast(op); + if (ip_op->get_layer_four_protocol() == vsomeip::sd::layer_four_protocol_e::UDP) { + EXPECT_EQ(vsomeip::sd::layer_four_protocol_e::UDP, ip_op->get_layer_four_protocol()); + udp_service_info = boost::asio::ip::udp::endpoint( + boost::asio::ip::address_v4(ip_op->get_address()), + ip_op->get_port()); + } + } + } + offer_received.set_value(); + service_offered = true; + } + } + if (service_offered && client_subscribed) { + keep_receiving = false; + } + } else { + ADD_FAILURE() << " received non-sd message"; + } + } + } + }); + + std::thread send_thread([&]() { + try { + boost::system::error_code ec; + udp_socket_service.set_option(boost::asio::socket_base::reuse_address(true), ec); + boost::asio::detail::throw_error(ec, "udp_socket_service set_option"); + + // offer the service + std::uint8_t its_offer_service_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x01, 0x00, 0x00, 0x20, + 0x33, 0x44, 0x00, 0x01, // service / instance + 0x00, 0xff, 0xff, 0xff, // major / ttl + 0x00, 0x00, 0x00, 0x00, // minor + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // slave address + 0x00, 0x11, 0x9c, 0x41, // offer via udp + }; + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_offer_service_message[48], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); + + // wait until client subscribed + if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't subscribe within time"; + } + + // wait until a offer was received + if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive offer within time"; + } + + // send malicious data as server (wrong protocol version) + std::uint8_t wrong_protocol_data[] = { + 0x33, 0x44, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xAA, 0xAA, 0xCA, 0xFE, + 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA + }; + udp_socket_service.send_to(boost::asio::buffer(wrong_protocol_data), udp_client_info); + + std::uint8_t wrong_message_type_data[] = { + 0x33, 0x44, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xBB, 0xBB, 0xCA, 0xFE, + 0x01, 0x00, 0xBB, 0x00 // message type set to 0xBB + }; + udp_socket_service.send_to(boost::asio::buffer(wrong_message_type_data), udp_client_info); + + std::uint8_t wrong_return_code_data[] = { + 0x33, 0x44, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xCC, 0xCC, 0xCA, 0xFE, + 0x01, 0x00, 0x00, 0xCC // return code set to 0xCC + }; + udp_socket_service.send_to(boost::asio::buffer(wrong_return_code_data), udp_client_info); + + std::uint8_t all_wrong_data[] = { + 0x33, 0x44, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xAA, 0xAA, 0xCA, 0xFE, + 0xAA, 0x00, 0xBB, 0xCC + }; + udp_socket_service.send_to(boost::asio::buffer(all_wrong_data), udp_client_info); + + udp_socket_service.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket_service.close(ec); + + // establish second UDP connection as client and send malicious data as well + std::atomic error_response_as_client_received(false); + + boost::asio::ip::udp::socket udp_socket_client(io_); + boost::asio::ip::udp::socket::endpoint_type remote( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket_client.open(remote.protocol()); + udp_socket_client.connect(remote); + + + std::thread udp_client_receive_thread([&]() { + std::atomic keep_receiving(true); + std::function receive; + std::vector receive_buffer(4096); + + auto receive_cbk = [&](const boost::system::error_code& _error, + std::size_t bytes_transferred) { + if (!_error) { + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + std::shared_ptr its_message(its_deserializer.deserialize_message()); + EXPECT_EQ(0x3345, its_message->get_service()); + EXPECT_EQ(0x1, its_message->get_method()); + EXPECT_EQ(0xCCCC, its_message->get_client()); + EXPECT_EQ(0xDDDD, its_message->get_session()); + EXPECT_EQ(vsomeip::return_code_e::E_WRONG_PROTOCOL_VERSION, its_message->get_return_code()); + EXPECT_EQ(vsomeip::message_type_e::MT_ERROR, its_message->get_message_type()); + error_response_as_client_received = true; + keep_receiving = false; + } else { + ADD_FAILURE() << __func__ << ":" << __LINE__ << " error: " << _error.message(); + return; + } + }; + + receive = [&]() { + udp_socket_client.async_receive(boost::asio::buffer(receive_buffer, receive_buffer.capacity()), + receive_cbk); + }; + + while (keep_receiving) { + receive(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + }); + + // send malicious data as client (too long length and wrong protocol version) + std::uint8_t wrong_protocol_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xCC, 0xCC, 0xDD, 0xDD, + 0xAA, 0x00, 0x00, 0x00 // protocol version set to 0xAA + }; + udp_socket_client.send_to(boost::asio::buffer(wrong_protocol_client_data), udp_service_info); + + std::uint8_t wrong_message_type_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xCC, 0xCC, 0xDD, 0xDD, + 0x01, 0x00, 0xBB, 0x00 // message type set to 0xBB + }; + udp_socket_client.send_to(boost::asio::buffer(wrong_message_type_client_data), udp_service_info); + + std::uint8_t wrong_return_code_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xCC, 0xCC, 0xDD, 0xDD, + 0x01, 0x00, 0x00, 0xCC // return code set to 0xCC + }; + udp_socket_client.send_to(boost::asio::buffer(wrong_return_code_client_data), udp_service_info); + + std::uint8_t all_wrong_client_data[] = { + 0x33, 0x45, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xCC, 0xCC, 0xDD, 0xDD, + 0xAA, 0x00, 0xBB, 0xCC + }; + udp_socket_client.send_to(boost::asio::buffer(all_wrong_client_data), udp_service_info); + + + udp_client_receive_thread.join(); + EXPECT_TRUE(error_response_as_client_received); + + udp_socket_client.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket_client.close(ec); + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x33, 0x45, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); + udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); + udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket2.close(ec); + } catch (const std::exception& _e) { + ADD_FAILURE() << "catched exception: " << _e.what(); + } + + }); + + send_thread.join(); + sd_receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + if(argc < 3) { + std::cerr << "Please pass an target, local IP address and test mode to this binary like: " + << argv[0] << " 10.0.3.1 10.0.3.202 EVENTS" << std::endl; + exit(1); + } + remote_address = argv[1]; + local_address = argv[2]; + std::string its_testmode = argv[3]; + if (its_testmode == std::string("MALICIOUS_EVENTS")) { + ::testing::GTEST_FLAG(filter) = "*send_malicious_events"; + } else if (its_testmode == std::string("PROTOCOL_VERSION")) { + ::testing::GTEST_FLAG(filter) = "*send_wrong_protocol_version"; + } else if (its_testmode == std::string("MESSAGE_TYPE")) { + ::testing::GTEST_FLAG(filter) = "*send_wrong_message_type"; + } else if (its_testmode == std::string("RETURN_CODE")) { + ::testing::GTEST_FLAG(filter) = "*send_wrong_return_code"; + } else if (its_testmode == std::string("WRONG_HEADER_FIELDS_UDP")) { + ::testing::GTEST_FLAG(filter) = "*wrong_header_fields_udp"; + } + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/malicious_data_tests/malicious_data_test_service.cpp b/test/network_tests/malicious_data_tests/malicious_data_test_service.cpp new file mode 100644 index 0000000..0227acb --- /dev/null +++ b/test/network_tests/malicious_data_tests/malicious_data_test_service.cpp @@ -0,0 +1,185 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "malicious_data_test_globals.hpp" + +class malicious_data_test_service { +public: + malicious_data_test_service(struct malicious_data_test::service_info _service_info, malicious_data_test::test_mode_e _testmode) : + service_info_(_service_info), + testmode_(_testmode), + app_(vsomeip::runtime::get()->create_application("malicious_data_test_service")), + wait_until_registered_(true), + wait_until_shutdown_method_called_(true), + received_events_(0), + received_methodcalls_(0), + offer_thread_(std::bind(&malicious_data_test_service::run, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&malicious_data_test_service::on_state, this, + std::placeholders::_1)); + + std::set its_eventgroups; + its_eventgroups.insert(_service_info.eventgroup_id); + app_->request_event(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_eventgroups, vsomeip::event_type_e::ET_EVENT, + vsomeip::reliability_type_e::RT_UNKNOWN); + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, service_info_.shutdown_method_id, + std::bind(&malicious_data_test_service::on_shutdown_method_called, this, + std::placeholders::_1)); + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.event_id, + std::bind(&malicious_data_test_service::on_event, this, + std::placeholders::_1)); + + app_->register_message_handler(static_cast(service_info_.service_id + 1u), + service_info_.instance_id, 0x1, + std::bind(&malicious_data_test_service::on_message, this, + std::placeholders::_1)); + + // request service of client + app_->request_service(service_info_.service_id, service_info_.instance_id); + app_->subscribe(service_info_.service_id, service_info_.instance_id, + service_info_.eventgroup_id, 0, + service_info_.event_id); + + app_->start(); + } + + ~malicious_data_test_service() { + if (testmode_ == malicious_data_test::test_mode_e::MALICIOUS_EVENTS) { + EXPECT_EQ(9u, received_events_); + EXPECT_EQ(9u, received_methodcalls_); + } + offer_thread_.join(); + } + + void offer() { + app_->offer_service(static_cast(service_info_.service_id + 1u), 0x1); + } + + void stop() { + app_->stop_offer_service(static_cast(service_info_.service_id + 1u), 0x1); + app_->clear_all_handler(); + app_->stop(); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_shutdown_method_called(const std::shared_ptr &_message) { + app_->send(vsomeip::runtime::get()->create_response(_message)); + VSOMEIP_WARNING << "************************************************************"; + VSOMEIP_WARNING << "Shutdown method called -> going down!"; + VSOMEIP_WARNING << "************************************************************"; + std::lock_guard its_lock(mutex_); + wait_until_shutdown_method_called_ = false; + condition_.notify_one(); + } + + void on_event(const std::shared_ptr &_message) { + EXPECT_EQ(service_info_.service_id, _message->get_service()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + EXPECT_EQ(service_info_.event_id, _message->get_method()); + EXPECT_EQ(std::uint32_t(0x7F), _message->get_length()); + received_events_++; + } + + void on_message(const std::shared_ptr &_message) { + EXPECT_EQ(static_cast(service_info_.service_id + 1u), _message->get_service()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + EXPECT_EQ(vsomeip::method_t(0x1), _message->get_method()); + EXPECT_EQ(std::uint32_t(0x7F), _message->get_length()); + received_methodcalls_++; + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + + while (wait_until_shutdown_method_called_) { + condition_.wait(its_lock); + } + stop(); + } + +private: + struct malicious_data_test::service_info service_info_; + malicious_data_test::test_mode_e testmode_; + std::shared_ptr app_; + + bool wait_until_registered_; + bool wait_until_shutdown_method_called_; + std::uint32_t received_events_; + std::uint32_t received_methodcalls_; + std::mutex mutex_; + std::condition_variable condition_; + std::thread offer_thread_; +}; + +malicious_data_test::test_mode_e its_testmode(malicious_data_test::test_mode_e::MALICIOUS_EVENTS); + +TEST(someip_malicious_data_test, block_subscription_handler) +{ + malicious_data_test_service its_sample(malicious_data_test::service, its_testmode); +} + + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + std::string its_passed_testmode = argv[1]; + if (its_passed_testmode == std::string("MALICIOUS_EVENTS")) { + its_testmode = malicious_data_test::test_mode_e::MALICIOUS_EVENTS; + } else if (its_passed_testmode == std::string("PROTOCOL_VERSION")) { + its_testmode = malicious_data_test::test_mode_e::PROTOCOL_VERSION; + } else if (its_passed_testmode == std::string("MESSAGE_TYPE")) { + its_testmode = malicious_data_test::test_mode_e::MESSAGE_TYPE; + } else if (its_passed_testmode == std::string("RETURN_CODE")) { + its_testmode = malicious_data_test::test_mode_e::RETURN_CODE; + } else if (its_passed_testmode == std::string("WRONG_HEADER_FIELDS_UDP")) { + its_testmode = malicious_data_test::test_mode_e::WRONG_HEADER_FIELDS_UDP; + } + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/npdu_tests/conf/npdu_test_client_no_npdu.json.in b/test/network_tests/npdu_tests/conf/npdu_test_client_no_npdu.json.in new file mode 100644 index 0000000..07cfe08 --- /dev/null +++ b/test/network_tests/npdu_tests/conf/npdu_test_client_no_npdu.json.in @@ -0,0 +1,39 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"info", + "console":"true" + }, + "applications": + [ + { + "name":"npdu_test_routing_manager_daemon_client_side", + "id":"0x6666" + }, + { + "name":"npdu_test_client_one", + "id":"0x1111" + }, + { + "name":"npdu_test_client_two", + "id":"0x2222" + }, + { + "name":"npdu_test_client_three", + "id":"0x3333" + }, + { + "name":"npdu_test_client_four", + "id":"0x4444" + } + ], + "routing":"npdu_test_routing_manager_daemon_client_side", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/npdu_tests/conf/npdu_test_client_npdu.json.in b/test/network_tests/npdu_tests/conf/npdu_test_client_npdu.json.in new file mode 100644 index 0000000..dc35023 --- /dev/null +++ b/test/network_tests/npdu_tests/conf/npdu_test_client_npdu.json.in @@ -0,0 +1,167 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"info", + "console":"true" + }, + "applications": + [ + { + "name":"npdu_test_routing_manager_daemon_client_side", + "id":"0x6666" + }, + { + "name":"npdu_test_client_one", + "id":"0x1111" + }, + { + "name":"npdu_test_client_two", + "id":"0x2222" + }, + { + "name":"npdu_test_client_three", + "id":"0x3333" + }, + { + "name":"npdu_test_client_four", + "id":"0x4444" + } + ], + "services": + [ + { + "service":"0x1000", + "instance":"0x0001", + "unicast":"@TEST_IP_MASTER@", + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + }, + "debounce-times": + { + "requests" : { + "0x1001" : { + "debounce-time" : "10", + "maximum-retention-time" : "100" + }, + "0x1002" : { + "debounce-time" : "20", + "maximum-retention-time" : "200" + }, + "0x1003" : { + "debounce-time" : "30", + "maximum-retention-time" : "300" + }, + "0x1004" : { + "debounce-time" : "40", + "maximum-retention-time" : "400" + } + } + } + }, + { + "service":"0x2000", + "instance":"0x0002", + "unicast":"@TEST_IP_MASTER@", + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + }, + "debounce-times" : { + "requests" : { + "0x2001" : { + "debounce-time" : "10", + "maximum-retention-time" : "100" + }, + "0x2002" : { + "debounce-time" : "20", + "maximum-retention-time" : "200" + }, + "0x2003" : { + "debounce-time" : "30", + "maximum-retention-time" : "300" + }, + "0x2004" : { + "debounce-time" : "40", + "maximum-retention-time" : "400" + } + } + } + }, + { + "service":"0x3000", + "instance":"0x0003", + "unicast":"@TEST_IP_MASTER@", + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + }, + "debounce-times" : { + "requests" : { + "0x3001" : { + "debounce-time" : "10", + "maximum-retention-time" : "100" + }, + "0x3002" : { + "debounce-time" : "20", + "maximum-retention-time" : "200" + }, + "0x3003" : { + "debounce-time" : "30", + "maximum-retention-time" : "300" + }, + "0x3004" : { + "debounce-time" : "40", + "maximum-retention-time" : "400" + } + } + } + }, + { + "service":"0x4000", + "instance":"0x0004", + "unicast":"@TEST_IP_MASTER@", + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + }, + "debounce-times": { + "requests" : { + "0x4001" : { + "debounce-time" : "10", + "maximum-retention-time" : "100" + }, + "0x4002" : { + "debounce-time" : "20", + "maximum-retention-time" : "200" + }, + "0x4003" : { + "debounce-time" : "30", + "maximum-retention-time" : "300" + }, + "0x4004" : { + "debounce-time" : "40", + "maximum-retention-time" : "400" + } + } + } + } + ], + "routing":"npdu_test_routing_manager_daemon_client_side", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/npdu_tests/conf/npdu_test_service_no_npdu.json.in b/test/network_tests/npdu_tests/conf/npdu_test_service_no_npdu.json.in new file mode 100644 index 0000000..b4c8eaa --- /dev/null +++ b/test/network_tests/npdu_tests/conf/npdu_test_service_no_npdu.json.in @@ -0,0 +1,87 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"info", + "console":"true" + }, + "applications": + [ + { + "name":"npdu_test_routing_manager_daemon_service_side", + "id":"0x6667" + }, + { + "name":"npdu_test_service_one", + "id":"0x1000" + }, + { + "name":"npdu_test_service_two", + "id":"0x2000" + }, + { + "name":"npdu_test_service_three", + "id":"0x3000" + }, + { + "name":"npdu_test_service_four", + "id":"0x4000" + } + ], + "services": + [ + { + "service":"0x6667", + "instance":"0x6666", + "unreliable":"60666" + }, + { + "service":"0x1000", + "instance":"0x0001", + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2000", + "instance":"0x0002", + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3000", + "instance":"0x0003", + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x4000", + "instance":"0x0004", + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + } + } + ], + "routing":"npdu_test_routing_manager_daemon_service_side", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/npdu_tests/conf/npdu_test_service_npdu.json.in b/test/network_tests/npdu_tests/conf/npdu_test_service_npdu.json.in new file mode 100644 index 0000000..0de75cf --- /dev/null +++ b/test/network_tests/npdu_tests/conf/npdu_test_service_npdu.json.in @@ -0,0 +1,168 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"info", + "console":"true" + }, + "applications": + [ + { + "name":"npdu_test_routing_manager_daemon_service_side", + "id":"0x6667" + }, + { + "name":"npdu_test_service_one", + "id":"0x1000" + }, + { + "name":"npdu_test_service_two", + "id":"0x2000" + }, + { + "name":"npdu_test_service_three", + "id":"0x3000" + }, + { + "name":"npdu_test_service_four", + "id":"0x4000" + } + ], + "services": + [ + { + "service":"0x6667", + "instance":"0x6666", + "unreliable":"60666" + }, + { + "service":"0x1000", + "instance":"0x0001", + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + }, + "debounce-times": + { + "responses" : { + "0x1001" : { + "debounce-time" : "10", + "maximum-retention-time" : "100" + }, + "0x1002" : { + "debounce-time" : "20", + "maximum-retention-time" : "200" + }, + "0x1003" : { + "debounce-time" : "30", + "maximum-retention-time" : "300" + }, + "0x1004" : { + "debounce-time" : "40", + "maximum-retention-time" : "400" + } + } + } + }, + { + "service":"0x2000", + "instance":"0x0002", + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + }, + "debounce-times" : { + "responses" : { + "0x2001" : { + "debounce-time" : "10", + "maximum-retention-time" : "100" + }, + "0x2002" : { + "debounce-time" : "20", + "maximum-retention-time" : "200" + }, + "0x2003" : { + "debounce-time" : "30", + "maximum-retention-time" : "300" + }, + "0x2004" : { + "debounce-time" : "40", + "maximum-retention-time" : "400" + } + } + } + }, + { + "service":"0x3000", + "instance":"0x0003", + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + }, + "debounce-times" : { + "responses" : { + "0x3001" : { + "debounce-time" : "10", + "maximum-retention-time" : "100" + }, + "0x3002" : { + "debounce-time" : "20", + "maximum-retention-time" : "200" + }, + "0x3003" : { + "debounce-time" : "30", + "maximum-retention-time" : "300" + }, + "0x3004" : { + "debounce-time" : "40", + "maximum-retention-time" : "400" + } + } + } + }, + { + "service":"0x4000", + "instance":"0x0004", + "unreliable":"30509", + "reliable": + { + "port":"30510", + "enable-magic-cookies":"false" + }, + "debounce-times": { + "responses" : { + "0x4001" : { + "debounce-time" : "10", + "maximum-retention-time" : "100" + }, + "0x4002" : { + "debounce-time" : "20", + "maximum-retention-time" : "200" + }, + "0x4003" : { + "debounce-time" : "30", + "maximum-retention-time" : "300" + }, + "0x4004" : { + "debounce-time" : "40", + "maximum-retention-time" : "400" + } + } + } + } + ], + "routing":"npdu_test_routing_manager_daemon_service_side", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp" + } +} diff --git a/test/network_tests/npdu_tests/npdu_test_client.cpp b/test/network_tests/npdu_tests/npdu_test_client.cpp new file mode 100644 index 0000000..d89d4f4 --- /dev/null +++ b/test/network_tests/npdu_tests/npdu_test_client.cpp @@ -0,0 +1,599 @@ +// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. +#include "../npdu_tests/npdu_test_client.hpp" + +#include +#include "../../implementation/configuration/include/configuration.hpp" +#include "../../implementation/configuration/include/configuration_impl.hpp" +#include "../../implementation/configuration/include/configuration_plugin.hpp" +#include "../../implementation/plugin/include/plugin_manager_impl.hpp" + +enum class payloadsize + : std::uint8_t + { + UDS, TCP, UDP +}; + +// this variables are changed via cmdline parameters +static bool use_tcp = false; +static bool call_service_sync = true; +static bool wait_for_replies = true; +static std::uint32_t sliding_window_size = vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND; +static payloadsize max_payload_size = payloadsize::UDS; +static bool shutdown_service_at_end = true; + +npdu_test_client::npdu_test_client( + bool _use_tcp, + bool _call_service_sync, + std::uint32_t _sliding_window_size, + bool _wait_for_replies, + std::array, 4> _applicative_debounce) : + app_(vsomeip::runtime::get()->create_application()), + request_(vsomeip::runtime::get()->create_request(_use_tcp)), + call_service_sync_(_call_service_sync), + wait_for_replies_(_wait_for_replies), + sliding_window_size_(_sliding_window_size), + blocked_({false}), + is_available_({false}), // will set first element to false, rest to 0 + number_of_messages_to_send_(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND), + number_of_sent_messages_{0,0,0,0}, + number_of_acknowledged_messages_{{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, + current_payload_size_({0}), + all_msg_acknowledged_({false, false, false, false}), + acknowledgements_{0,0,0,0}, + applicative_debounce_(_applicative_debounce), + finished_waiter_(&npdu_test_client::wait_for_all_senders, this) +{ + senders_[0] = std::thread(&npdu_test_client::run<0>, this); + senders_[1] = std::thread(&npdu_test_client::run<1>, this); + senders_[2] = std::thread(&npdu_test_client::run<2>, this); + senders_[3] = std::thread(&npdu_test_client::run<3>, this); +} + +npdu_test_client::~npdu_test_client() { + finished_waiter_.join(); +} + +void npdu_test_client::init() +{ + app_->init(); + + app_->register_state_handler( + std::bind(&npdu_test_client::on_state, this, + std::placeholders::_1)); + + register_availability_handler<0>(); + register_availability_handler<1>(); + register_availability_handler<2>(); + register_availability_handler<3>(); + + register_message_handler_for_all_service_methods<0>(); + register_message_handler_for_all_service_methods<1>(); + register_message_handler_for_all_service_methods<2>(); + register_message_handler_for_all_service_methods<3>(); + + request_->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request_->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + if(!wait_for_replies_) + request_->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); +} + +template +void npdu_test_client::register_availability_handler() { + app_->register_availability_handler(npdu_test::service_ids[service_idx], + npdu_test::instance_ids[service_idx], + std::bind( + &npdu_test_client::on_availability, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); +} + +template +void npdu_test_client::register_message_handler_for_all_service_methods() { + register_message_handler(); + register_message_handler(); + register_message_handler(); + register_message_handler(); +} + +template +void npdu_test_client::register_message_handler() { + app_->register_message_handler(npdu_test::service_ids[service_idx], + npdu_test::instance_ids[service_idx], + npdu_test::method_ids[service_idx][method_idx], + std::bind( + &npdu_test_client::on_message, + this, std::placeholders::_1)); +} + +void npdu_test_client::start() +{ + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void npdu_test_client::stop() +{ + VSOMEIP_INFO << "Stopping..."; + + app_->unregister_state_handler(); + + for (unsigned int i = 0; i< npdu_test::service_ids.size(); i++) { + app_->unregister_availability_handler(npdu_test::service_ids[i], + npdu_test::instance_ids[i]); + + for(unsigned int j = 0; j < npdu_test::method_ids[i].size(); j++) { + app_->unregister_message_handler(npdu_test::service_ids[i], + npdu_test::instance_ids[i], + npdu_test::method_ids[i][j]); + } + } + + if(shutdown_service_at_end) { + // notify the routing manager daemon that were finished + request_->set_service(npdu_test::RMD_SERVICE_ID_CLIENT_SIDE); + request_->set_instance(npdu_test::RMD_INSTANCE_ID); + request_->set_method(npdu_test::RMD_SHUTDOWN_METHOD_ID); + request_->set_payload(vsomeip::runtime::get()->create_payload()); + request_->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + app_->send(request_); + // sleep otherwise the app will shutdown before the message reaches the rmd + std::this_thread::sleep_for(std::chrono::seconds(5)); + } + app_->stop(); +} + +void npdu_test_client::join_sender_thread() { + for (auto& t : senders_) { + t.join(); + } +} + +void npdu_test_client::on_state(vsomeip::state_type_e _state) +{ + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + for (unsigned int i = 0; i< npdu_test::service_ids.size(); i++) { + app_->request_service(npdu_test::service_ids[i], + npdu_test::instance_ids[i]); + } + } +} + +template +void npdu_test_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) +{ + VSOMEIP_INFO<< "Service [" << std::setw(4) << std::setfill('0') << std::hex + << _service << "." << std::setw(4) << std::setfill('0') << _instance << "] is " + << (_is_available ? "available." : "NOT available."); + if(npdu_test::service_ids[service_idx] == _service + && npdu_test::instance_ids[service_idx] == _instance) { + if(is_available_[service_idx] && !_is_available) + { + is_available_[service_idx] = false; + } + else if(_is_available && !is_available_[service_idx]) + { + is_available_[service_idx] = true; + send(); + } + } +} + +template +void npdu_test_client::on_message(const std::shared_ptr& _response) { + (void)_response; + //TODO make sure the replies were sent within demanded debounce times + VSOMEIP_DEBUG << "Received reply from:" << std::setw(4) << std::setfill('0') + << std::hex << npdu_test::service_ids[service_idx] << ":" + << std::setw(4) << std::setfill('0') << std::hex + << npdu_test::instance_ids[service_idx] << ":" << std::setw(4) + << std::setfill('0') << std::hex + << npdu_test::method_ids[service_idx][method_idx]; + + if(call_service_sync_) + { + // We notify the sender thread every time a message was acknowledged + std::lock_guard lk(all_msg_acknowledged_mutexes_[service_idx][method_idx]); + all_msg_acknowledged_[service_idx][method_idx] = true; + all_msg_acknowledged_cvs_[service_idx][method_idx].notify_one(); + } + else + { + + std::lock_guard its_lock(number_of_acknowledged_messages_mutexes_[service_idx][method_idx]); + number_of_acknowledged_messages_[service_idx][method_idx]++; + + // We notify the sender thread only if all sent messages have been acknowledged + if(number_of_acknowledged_messages_[service_idx][method_idx] == number_of_messages_to_send_) + { + std::lock_guard lk(all_msg_acknowledged_mutexes_[service_idx][method_idx]); + // reset + number_of_acknowledged_messages_[service_idx][method_idx] = 0; + all_msg_acknowledged_[service_idx][method_idx] = true; + all_msg_acknowledged_cvs_[service_idx][method_idx].notify_one(); + } else if(number_of_acknowledged_messages_[service_idx][method_idx] % sliding_window_size == 0) + { + std::lock_guard lk(all_msg_acknowledged_mutexes_[service_idx][method_idx]); + all_msg_acknowledged_[service_idx][method_idx] = true; + all_msg_acknowledged_cvs_[service_idx][method_idx].notify_one(); + } + } +} + +template +void npdu_test_client::send() +{ + std::lock_guard its_lock(mutexes_[service_idx]); + blocked_[service_idx] = true; + conditions_[service_idx].notify_one(); +} + +template +void npdu_test_client::run() +{ + std::unique_lock its_lock(mutexes_[service_idx]); + while (!blocked_[service_idx]) + { + conditions_[service_idx].wait(its_lock); + } + current_payload_size_[service_idx] = 1; + + std::uint32_t max_allowed_payload = get_max_allowed_payload(); + + for (int var = 0; var < 4; ++var) { + payloads_[service_idx][var] = vsomeip::runtime::get()->create_payload(); + payload_data_[service_idx][var] = std::vector(); + } + + bool lastrun = false; + while (current_payload_size_[service_idx] <= max_allowed_payload) + { + // prepare the payloads w/ current payloadsize + for (int var = 0; var < 4; ++var) { + // assign 0x11 to first, 0x22 to second... + payload_data_[service_idx][var].assign( + current_payload_size_[service_idx], static_cast(0x11 * (var + 1))); + payloads_[service_idx][var]->set_data(payload_data_[service_idx][var]); + } + + // send the payloads to the service's methods + if(wait_for_replies_) { + call_service_sync_ ? send_messages_sync() : send_messages_async(); + } else { + send_messages_and_dont_wait_for_reply(); + } + + // Increase array size for next iteration + current_payload_size_[service_idx] *= 2; + + //special case to test the biggest payload possible as last test + // 16 Bytes are reserved for the SOME/IP header + if(current_payload_size_[service_idx] > max_allowed_payload - 16 && !lastrun) + { + current_payload_size_[service_idx] = max_allowed_payload - 16; + lastrun = true; + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + blocked_[service_idx] = false; + + { + std::lock_guard its_lock(finished_mutex_); + finished_[service_idx] = true; + } +} + + +std::uint32_t npdu_test_client::get_max_allowed_payload() +{ + std::uint32_t payload; + switch (max_payload_size) + { + case payloadsize::UDS: + payload = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE; + break; + case payloadsize::TCP: + payload = 4095; + break; + case payloadsize::UDP: + payload = VSOMEIP_MAX_UDP_MESSAGE_SIZE; + break; + default: + payload = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE; + break; + } + return payload; +} + +template +void npdu_test_client::send_messages_sync() +{ + std::thread t0 = start_send_thread_sync(); + std::thread t1 = start_send_thread_sync(); + std::thread t2 = start_send_thread_sync(); + std::thread t3 = start_send_thread_sync(); + t0.join(); + t1.join(); + t2.join(); + t3.join(); +} + +template +std::thread npdu_test_client::start_send_thread_sync() { + return std::thread([&]() { + all_msg_acknowledged_unique_locks_[service_idx][method_idx] = + std::unique_lock + (all_msg_acknowledged_mutexes_[service_idx][method_idx]); + + std::shared_ptr request = vsomeip::runtime::get()->create_request(use_tcp); + request->set_service(npdu_test::service_ids[service_idx]); + request->set_instance(npdu_test::instance_ids[service_idx]); + request->set_method(npdu_test::method_ids[service_idx][method_idx]); + request->set_payload(payloads_[service_idx][method_idx]); + for (std::uint32_t i = 0; i < number_of_messages_to_send_; i++) + { + all_msg_acknowledged_[service_idx][method_idx] = false; + app_->send(request); + + std::chrono::high_resolution_clock::time_point sent = + std::chrono::high_resolution_clock::now(); + + while(!all_msg_acknowledged_[service_idx][method_idx]) { + all_msg_acknowledged_cvs_[service_idx][method_idx].wait( + all_msg_acknowledged_unique_locks_[service_idx][method_idx]); + } + + std::chrono::nanoseconds waited_for_response = + std::chrono::high_resolution_clock::now() - sent; + if(waited_for_response < applicative_debounce_[service_idx][method_idx]) { + // make sure we don't send faster than debounce time + max retention time + std::this_thread::sleep_for( + applicative_debounce_[service_idx][method_idx] + - waited_for_response); + } + } + all_msg_acknowledged_unique_locks_[service_idx][method_idx].unlock(); + }); +} + +template +void npdu_test_client::send_messages_async() +{ + std::thread t0 = start_send_thread_async(); + std::thread t1 = start_send_thread_async(); + std::thread t2 = start_send_thread_async(); + std::thread t3 = start_send_thread_async(); + t0.join(); + t1.join(); + t2.join(); + t3.join(); +} + +template +std::thread npdu_test_client::start_send_thread_async() { + return std::thread([&]() { + all_msg_acknowledged_unique_locks_[service_idx][method_idx] = + std::unique_lock + (all_msg_acknowledged_mutexes_[service_idx][method_idx]); + std::shared_ptr request = vsomeip::runtime::get()->create_request(use_tcp); + request->set_service(npdu_test::service_ids[service_idx]); + request->set_instance(npdu_test::instance_ids[service_idx]); + request->set_method(npdu_test::method_ids[service_idx][method_idx]); + request->set_payload(payloads_[service_idx][method_idx]); + for (std::uint32_t i = 0; i < number_of_messages_to_send_; i++) + { + app_->send(request); + + if((i+1) == number_of_messages_to_send_ || (i+1) % sliding_window_size == 0) { + // wait until all send messages have been acknowledged + // as long we wait lk is released; after wait returns lk is reacquired + while(!all_msg_acknowledged_[service_idx][method_idx]) { + all_msg_acknowledged_cvs_[service_idx][method_idx].wait( + all_msg_acknowledged_unique_locks_[service_idx][method_idx]); + } + // Reset condition variable + all_msg_acknowledged_[service_idx][method_idx] = false; + } + // make sure we don't send faster than debounce time + max retention time + std::this_thread::sleep_for(applicative_debounce_[service_idx][method_idx]); + } + all_msg_acknowledged_unique_locks_[service_idx][method_idx].unlock(); + }); +} + +template +void npdu_test_client::send_messages_and_dont_wait_for_reply() +{ + std::thread t0 = start_send_thread(); + std::thread t1 = start_send_thread(); + std::thread t2 = start_send_thread(); + std::thread t3 = start_send_thread(); + t0.join(); + t1.join(); + t2.join(); + t3.join(); +} + +template +std::thread npdu_test_client::start_send_thread() { + return std::thread([&]() { + std::shared_ptr request = vsomeip::runtime::get()->create_request(use_tcp); + request->set_service(npdu_test::service_ids[service_idx]); + request->set_instance(npdu_test::instance_ids[service_idx]); + request->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + request->set_method(npdu_test::method_ids[service_idx][method_idx]); + request->set_payload(payloads_[service_idx][method_idx]); + for (std::uint32_t i = 0; i < number_of_messages_to_send_; i++) + { + app_->send(request); + // make sure we don't send faster than debounce time + max retention time + std::this_thread::sleep_for(applicative_debounce_[service_idx][method_idx]); + } + }); +} + +void npdu_test_client::wait_for_all_senders() { + bool all_finished(false); + while (!all_finished) { + { + std::lock_guard its_lock(finished_mutex_); + if (std::all_of(finished_.begin(), finished_.end(), [](bool i) { return i; })) { + all_finished = true; + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + join_sender_thread(); + + if (!wait_for_replies_ || !call_service_sync_) { + // sleep longer here as sending is asynchronously and it's necessary + // to wait until all messages have left the application + VSOMEIP_INFO << "Sleeping for 180sec since the client is running " + "in --dont-wait-for-replies or --async mode. " + "Otherwise it might be possible that not all messages leave the " + "application."; + for(int i = 0; i < 180; i++) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + std::cout << "."; + std::cout.flush(); + } + } else { + std::this_thread::sleep_for(std::chrono::seconds(5)); + } + stop(); +} + +TEST(someip_npdu_test, send_different_payloads) +{ + // get the configuration + std::shared_ptr its_configuration; + auto its_plugin = vsomeip::plugin_manager::get()->get_plugin( + vsomeip::plugin_type_e::CONFIGURATION_PLUGIN, VSOMEIP_CFG_LIBRARY); + if (its_plugin) { + auto its_config_plugin = std::dynamic_pointer_cast(its_plugin); + if (its_config_plugin) { + its_configuration = its_config_plugin->get_configuration("",""); + } + } + if (!its_configuration) { + ADD_FAILURE() << "No configuration object. " + "Either memory overflow or loading error detected!"; + return; + } + + // used to store the debounce times + std::array, 4> applicative_debounce; + + // query the debouncetimes from the configuration. We want to know the + // debounce times which the _clients_ of this service have to comply with + // when they send requests to this service. + // This is necessary as we must ensure a applicative debouncing greater than + // debounce time + maximum retention time. Therefore the send threads sleep + // for this amount of time after sending a message. + for(int service_id = 0; service_id < 4; service_id++) { + for(int method_id = 0; method_id < 4; method_id++) { + std::chrono::nanoseconds debounce(0), retention(0); + its_configuration->get_configured_timing_requests( + npdu_test::service_ids[service_id], + its_configuration->get_unicast_address(npdu_test::service_ids[service_id], + npdu_test::instance_ids[service_id]), + its_configuration->get_unreliable_port( + npdu_test::service_ids[service_id], + npdu_test::instance_ids[service_id]), + npdu_test::method_ids[service_id][method_id], + &debounce, &retention); + if (debounce == std::chrono::nanoseconds(VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO) && + retention == std::chrono::nanoseconds(VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO)) { + // no timings specified don't don't sleep after sending... + applicative_debounce[service_id][method_id] = + std::chrono::milliseconds(0); + } else { + // we add 1 milliseconds to sleep a little bit longer + applicative_debounce[service_id][method_id] = std::chrono::duration_cast< + std::chrono::milliseconds>(debounce + retention) + + std::chrono::milliseconds(1); + + } + + } + } + + npdu_test_client test_client_(use_tcp, call_service_sync, + sliding_window_size, wait_for_replies, + applicative_debounce); + test_client_.init(); + test_client_.start(); +} + + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + std::string tcp_enable("--TCP"); + std::string udp_enable("--UDP"); + std::string sync_enable("--sync"); + std::string async_enable("--async"); + std::string no_reply_enable("--dont-wait-for-replies"); + std::string sliding_window_size_param("--sliding-window-size"); + std::string max_payload_size_param("--max-payload-size"); + std::string shutdown_service_disable_param("--dont-shutdown-service"); + std::string help("--help"); + + int i = 1; + while (i < argc) + { + if (tcp_enable == argv[i]) { + use_tcp = true; + } else if (udp_enable == argv[i]) { + use_tcp = false; + } else if (sync_enable == argv[i]) { + call_service_sync = true; + } else if (async_enable == argv[i]) { + call_service_sync = false; + } else if (no_reply_enable == argv[i]) { + wait_for_replies = false; + } else if (sliding_window_size_param == argv[i] && i + 1 < argc) { + i++; + std::stringstream converter(argv[i]); + converter >> sliding_window_size; + } else if (max_payload_size_param == argv[i] && i + 1 < argc) { + i++; + if (std::string("UDS") == argv[i]) { + max_payload_size = payloadsize::UDS; + } else if (std::string("TCP") == argv[i]) { + max_payload_size = payloadsize::TCP; + } else if (std::string("UDP") == argv[i]) { + max_payload_size = payloadsize::UDP; + } + } else if (shutdown_service_disable_param == argv[i]) { + shutdown_service_at_end = false; + } else if (help == argv[i]) { + VSOMEIP_INFO << "Parameters:\n" + << "--TCP: Send messages via TCP\n" + << "--UDP: Send messages via UDP (default)\n" + << "--sync: Wait for acknowledge before sending next message (default)\n" + << "--async: Send multiple messages w/o waiting for" + " acknowledge of service\n" + << "--dont-wait-for-replies: Just send out the messages w/o waiting for " + "a reply by the service (use REQUEST_NO_RETURN message type)\n" + << "--sliding-window-size: Number of messages to send before waiting " + "for acknowledge of service. Default: " << sliding_window_size << "\n" + << "--max-payload-size: limit the maximum payloadsize of send requests. One of {" + "UDS (=" << VSOMEIP_MAX_LOCAL_MESSAGE_SIZE << "byte), " + "UDP (=" << VSOMEIP_MAX_UDP_MESSAGE_SIZE << "byte), " + "TCP (=" << VSOMEIP_MAX_TCP_MESSAGE_SIZE << "byte)}, default: UDS\n" + << "--dont-shutdown-service: Don't shutdown the service upon " + "finishing of the payload test\n" + << "--help: print this help"; + } + i++; + } + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/npdu_tests/npdu_test_client.hpp b/test/network_tests/npdu_tests/npdu_test_client.hpp new file mode 100644 index 0000000..980c16a --- /dev/null +++ b/test/network_tests/npdu_tests/npdu_test_client.hpp @@ -0,0 +1,103 @@ +// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef PAYLOADTESTCLIENT_HPP_ +#define NPDUTESTCLIENT_HPP_ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "../npdu_tests/npdu_test_globals.hpp" +#include "../someip_test_globals.hpp" + +class npdu_test_client +{ +public: + npdu_test_client(bool _use_tcp, bool _call_service_sync, + std::uint32_t _sliding_window_size, + bool _wait_for_replies, + std::array, 4> _applicative_debounce); + ~npdu_test_client(); + void init(); + void start(); + void stop(); + void join_sender_thread(); + void on_state(vsomeip::state_type_e _state); + template void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, + bool _is_available); + template void on_message( + const std::shared_ptr &_response); + template void send(); + template void run(); + +private: + template void send_messages_sync(); + template std::thread start_send_thread_sync(); + template void send_messages_async(); + template std::thread start_send_thread_async(); + template void send_messages_and_dont_wait_for_reply(); + std::uint32_t get_max_allowed_payload(); + template void register_availability_handler(); + template void register_message_handler_for_all_service_methods(); + template void register_message_handler(); + template + std::thread start_send_thread(); + void wait_for_all_senders(); + +private: + std::shared_ptr app_; + std::shared_ptr request_; + bool call_service_sync_; + bool wait_for_replies_; + std::uint32_t sliding_window_size_; + + std::array mutexes_; + std::array conditions_; + std::array blocked_; + std::array is_available_; + const std::uint32_t number_of_messages_to_send_; + std::uint32_t number_of_sent_messages_[npdu_test::service_ids.size()]; + std::array, + npdu_test::service_ids.size()> number_of_acknowledged_messages_; + std::array, + npdu_test::service_ids.size()> number_of_acknowledged_messages_mutexes_; + + std::array current_payload_size_; + + std::array, + npdu_test::service_ids.size()> all_msg_acknowledged_; + std::array, + npdu_test::service_ids.size()> all_msg_acknowledged_mutexes_; + std::array, npdu_test::method_ids[0].size()>, + npdu_test::service_ids.size()> all_msg_acknowledged_unique_locks_; + std::array< + std::array, + npdu_test::service_ids.size()> all_msg_acknowledged_cvs_; + std::array acknowledgements_; + std::array, 4> applicative_debounce_; + std::array< + std::array, + npdu_test::method_ids[0].size()>, + npdu_test::service_ids.size()> payloads_; + std::array< + std::array, + npdu_test::method_ids[0].size()>, + npdu_test::service_ids.size()> payload_data_; + std::array senders_; + std::mutex finished_mutex_; + std::array finished_; + std::thread finished_waiter_; +}; + +#endif /* NPDUTESTCLIENT_HPP_ */ diff --git a/test/network_tests/npdu_tests/npdu_test_client_no_npdu_start.sh b/test/network_tests/npdu_tests/npdu_test_client_no_npdu_start.sh new file mode 100755 index 0000000..bc84421 --- /dev/null +++ b/test/network_tests/npdu_tests/npdu_test_client_no_npdu_start.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the routing manager daemon and the +# clients with one command. This is necessary as ctest - which is used to run +# the tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the routing +# manager daemon and the clients and checks if all of them exit successfully. + +FAIL=0 + +if [ $# -lt 2 ]; then + echo "Error: Please pass a protocol and communication mode to this script." + echo "Valid protocols are [UDP,TCP]." + echo "Valid communication modes are [sync, async]." + echo "For example $> $0 UDP sync" + exit 1; +fi + +FAIL=0 +PROTOCOL=$1 +COMMUNICATION_MODE=$2 + +start_clients(){ + export VSOMEIP_CONFIGURATION=npdu_test_client_no_npdu.json + + # Start the routing manager daemon + export VSOMEIP_APPLICATION_NAME=npdu_test_routing_manager_daemon_client_side + ./npdu_test_rmd_client_side & + + # sleep 1 second to let the RMD startup. + sleep 1 + # Start client 1 + export VSOMEIP_APPLICATION_NAME=npdu_test_client_one + ./npdu_test_client_1 $* & + + # Start client 2 + export VSOMEIP_APPLICATION_NAME=npdu_test_client_two + ./npdu_test_client_2 $* & + + # Start client 3 + export VSOMEIP_APPLICATION_NAME=npdu_test_client_three + ./npdu_test_client_3 $* & + + # Start client 4 + export VSOMEIP_APPLICATION_NAME=npdu_test_client_four + ./npdu_test_client_4 $* & +} + +wait_for_bg_processes(){ + # Wait until client and service are finished + for job in $(jobs -p) + do + # Fail gets incremented if one of the jobs exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) + done + + # Check if everything exited successfully + if [ $FAIL -eq 0 ] + then + echo "All clients exited successfully" + else + echo "Something went wrong" + exit 1 + fi +} + +if [ $# -eq 0 ] +then + echo "Error: Please pass a mode to this script: UDP or TCP." + echo "For example $> $0 UDP" +fi + +echo "Contacting services via $PROTOCOL" +start_clients --$PROTOCOL --max-payload-size $PROTOCOL --$COMMUNICATION_MODE +wait_for_bg_processes + +exit 0 diff --git a/test/network_tests/npdu_tests/npdu_test_client_npdu_start.sh b/test/network_tests/npdu_tests/npdu_test_client_npdu_start.sh new file mode 100755 index 0000000..70b6c53 --- /dev/null +++ b/test/network_tests/npdu_tests/npdu_test_client_npdu_start.sh @@ -0,0 +1,75 @@ +#!/bin/bash +# Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the routing manager daemon and the +# clients with one command. This is necessary as ctest - which is used to run +# the tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the routing +# manager daemon and the clients and checks if all of them exit successfully. + +if [ $# -lt 2 ]; then + echo "Error: Please pass a protocol and communication mode to this script." + echo "Valid protocols are [UDP,TCP]." + echo "Valid communication modes are [sync, async]." + echo "For example $> $0 UDP sync" + exit 1; +fi + +FAIL=0 +PROTOCOL=$1 +COMMUNICATION_MODE=$2 + +start_clients(){ + export VSOMEIP_CONFIGURATION=npdu_test_client_npdu.json + + # Start the routing manager daemon + export VSOMEIP_APPLICATION_NAME=npdu_test_routing_manager_daemon_client_side + ./npdu_test_rmd_client_side & + + # sleep 1 second to let the RMD startup. + sleep 1 + # Start client 1 + export VSOMEIP_APPLICATION_NAME=npdu_test_client_one + ./npdu_test_client_1 $* & + + # Start client 2 + export VSOMEIP_APPLICATION_NAME=npdu_test_client_two + ./npdu_test_client_2 $* & + + # Start client 3 + export VSOMEIP_APPLICATION_NAME=npdu_test_client_three + ./npdu_test_client_3 $* & + + # Start client 4 + export VSOMEIP_APPLICATION_NAME=npdu_test_client_four + ./npdu_test_client_4 $* & +} + +wait_for_bg_processes(){ + # Wait until client and service are finished + for job in $(jobs -p) + do + # Fail gets incremented if one of the jobs exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) + done + + # Check if everything exited successfully + if [ $FAIL -eq 0 ] + then + echo "All clients exited successfully" + else + echo "Something went wrong" + exit 1 + fi +} + + +echo "Contacting services via $PROTOCOL" +start_clients --$PROTOCOL --max-payload-size $PROTOCOL --$COMMUNICATION_MODE +wait_for_bg_processes + +exit 0 diff --git a/test/network_tests/npdu_tests/npdu_test_globals.hpp b/test/network_tests/npdu_tests/npdu_test_globals.hpp new file mode 100644 index 0000000..8cee3ee --- /dev/null +++ b/test/network_tests/npdu_tests/npdu_test_globals.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef NPDU_TESTS_NPDU_TEST_GLOBALS_HPP_ +#define NPDU_TESTS_NPDU_TEST_GLOBALS_HPP_ + +namespace npdu_test { + +// Routing manager daemon +constexpr vsomeip::client_t RMD_CLIENT_ID_CLIENT_SIDE = 0x6666; +constexpr vsomeip::service_t RMD_SERVICE_ID_CLIENT_SIDE = 0x6666; + +constexpr vsomeip::client_t RMD_CLIENT_ID_SERVICE_SIDE = 0x6667; +constexpr vsomeip::service_t RMD_SERVICE_ID_SERVICE_SIDE = 0x6667; + +constexpr vsomeip::instance_t RMD_INSTANCE_ID = 0x6666; +constexpr vsomeip::method_t RMD_SHUTDOWN_METHOD_ID = 0x6666; + + + +constexpr vsomeip::method_t NPDU_SERVICE_SHUTDOWNMETHOD_ID = 0x7777; + +constexpr std::array service_ids = + { 0x1000, 0x2000, 0x3000, 0x4000 }; +constexpr std::array instance_ids = + { service_ids[0] >> 12, + service_ids[1] >> 12, + service_ids[2] >> 12, + service_ids[3] >> 12 }; +constexpr std::array, 4> method_ids = {{ + { service_ids[0]+1, service_ids[0]+2 ,service_ids[0]+3 ,service_ids[0]+4 }, + { service_ids[1]+1, service_ids[1]+2 ,service_ids[1]+3 ,service_ids[1]+4 }, + { service_ids[2]+1, service_ids[2]+2 ,service_ids[2]+3 ,service_ids[2]+4 }, + { service_ids[3]+1, service_ids[3]+2 ,service_ids[3]+3 ,service_ids[3]+4 } +}}; + +constexpr std::array client_ids_clients = + { 0x1111, 0x2222, 0x3333, 0x4444 }; + +constexpr std::array client_ids_services = service_ids; + +} +#endif /* NPDU_TESTS_NPDU_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/npdu_tests/npdu_test_rmd.cpp b/test/network_tests/npdu_tests/npdu_test_rmd.cpp new file mode 100644 index 0000000..8e5451b --- /dev/null +++ b/test/network_tests/npdu_tests/npdu_test_rmd.cpp @@ -0,0 +1,160 @@ +// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../npdu_tests/npdu_test_rmd.hpp" + +#include +#include "npdu_test_globals.hpp" + +#include "../npdu_tests/npdu_test_globals.hpp" + +npdu_test_rmd::npdu_test_rmd() : + app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + blocked_(false), + offer_thread_(std::bind(&npdu_test_rmd::run, this)) +{ + // TODO Auto-generated constructor stub +} + +void npdu_test_rmd::init() { + std::lock_guard its_lock(mutex_); + + app_->init(); + +#ifdef RMD_CLIENT_SIDE + app_->register_message_handler(npdu_test::RMD_SERVICE_ID_CLIENT_SIDE, +#elif defined (RMD_SERVICE_SIDE) + app_->register_message_handler(npdu_test::RMD_SERVICE_ID_SERVICE_SIDE, +#endif + npdu_test::RMD_INSTANCE_ID, npdu_test::RMD_SHUTDOWN_METHOD_ID, + std::bind(&npdu_test_rmd::on_message_shutdown, + this, std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&npdu_test_rmd::on_state, this, + std::placeholders::_1)); +} + +void npdu_test_rmd::start() { + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void npdu_test_rmd::stop() { + VSOMEIP_INFO << "Stopping..."; + + app_->unregister_message_handler(npdu_test::RMD_SERVICE_ID_CLIENT_SIDE, + npdu_test::RMD_INSTANCE_ID, npdu_test::RMD_SHUTDOWN_METHOD_ID); + app_->unregister_state_handler(); + offer_thread_.join(); + app_->stop(); +} + +void npdu_test_rmd::on_state( + vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : + "deregistered."); + + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + if(!is_registered_) + { + std::lock_guard its_lock(mutex_); + is_registered_ = true; + blocked_ = true; + // "start" the run method thread + condition_.notify_one(); + } + } + else + { + is_registered_ = false; + } +} + +void npdu_test_rmd::on_message_shutdown( + const std::shared_ptr& _request) { + (void)_request; + std::shared_ptr request = vsomeip::runtime::get()->create_request(false); +#ifdef RMD_CLIENT_SIDE + static uint32_t counter = 0; + counter++; + VSOMEIP_INFO << counter << " of " << npdu_test::client_ids_clients.size() + << " clients are finished."; + + if (counter == npdu_test::client_ids_clients.size()) { + VSOMEIP_INFO << "All clients are finished, notify routing manager daemon on service side."; + // notify the RMD_SERVICE_SIDE that he can shutdown as well + std::this_thread::sleep_for(std::chrono::seconds(1)); + request->set_service(npdu_test::RMD_SERVICE_ID_SERVICE_SIDE); + request->set_instance(npdu_test::RMD_INSTANCE_ID); + request->set_method(npdu_test::RMD_SHUTDOWN_METHOD_ID); + request->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + app_->send(request); + std::this_thread::sleep_for(std::chrono::seconds(5)); + stop(); + } +#elif defined RMD_SERVICE_SIDE + VSOMEIP_INFO << "All clients are finished shutting down services"; + // shutdown all services + for(unsigned int i = 0; i < npdu_test::service_ids.size(); i++) { + request->set_service(npdu_test::service_ids[i]); + request->set_instance(npdu_test::instance_ids[i]); + request->set_method(npdu_test::NPDU_SERVICE_SHUTDOWNMETHOD_ID); + request->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + app_->send(request); + } + app_->stop_offer_service(npdu_test::RMD_SERVICE_ID_SERVICE_SIDE, npdu_test::RMD_INSTANCE_ID); + + VSOMEIP_INFO << "Wait a few seconds until all services are shutdown."; + std::atomic finished(false); + for (int i = 0; !finished && i < 20; i++) { + app_->get_offered_services_async( + vsomeip::offer_type_e::OT_REMOTE, + [&](const std::vector> &_services){ + if (_services.empty()) { + finished = true; + } + }); + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + stop(); +#endif +} + +void npdu_test_rmd::join_shutdown_thread() { + shutdown_thread_.join(); +} + +void npdu_test_rmd::run() { + std::unique_lock its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); +#ifdef RMD_CLIENT_SIDE + app_->offer_service(npdu_test::RMD_SERVICE_ID_CLIENT_SIDE, npdu_test::RMD_INSTANCE_ID); +#elif defined (RMD_SERVICE_SIDE) + app_->offer_service(npdu_test::RMD_SERVICE_ID_SERVICE_SIDE, npdu_test::RMD_INSTANCE_ID); +#endif +} + +TEST(someip_npdu_test, offer_routing_manager_functionality) +{ + npdu_test_rmd daemon; + daemon.init(); + daemon.start(); +} + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + + diff --git a/test/network_tests/npdu_tests/npdu_test_rmd.hpp b/test/network_tests/npdu_tests/npdu_test_rmd.hpp new file mode 100644 index 0000000..0b1e28d --- /dev/null +++ b/test/network_tests/npdu_tests/npdu_test_rmd.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef NPDU_TESTS_NPDUTESTROUTINGMANAGERDAEMON_HPP_ +#define NPDU_TESTS_NPDUTESTROUTINGMANAGERDAEMON_HPP_ + +#include + +#include + +#include +#include +#include +#include + +class npdu_test_rmd { + +public: + npdu_test_rmd(); + void init(); + void start(); + void stop(); + void on_state(vsomeip::state_type_e _state); + void on_message_shutdown(const std::shared_ptr &_request); + void join_shutdown_thread(); + void run(); + +private: + std::shared_ptr app_; + bool is_registered_; + + std::mutex mutex_; + std::mutex mutex2_; + std::condition_variable condition_; + std::condition_variable condition2_; + bool blocked_; + bool blocked2_; + std::thread offer_thread_; + std::thread shutdown_thread_; + +}; + +#endif /* NPDU_TESTS_NPDUTESTROUTINGMANAGERDAEMON_HPP_ */ diff --git a/test/network_tests/npdu_tests/npdu_test_service.cpp b/test/network_tests/npdu_tests/npdu_test_service.cpp new file mode 100644 index 0000000..b4ee984 --- /dev/null +++ b/test/network_tests/npdu_tests/npdu_test_service.cpp @@ -0,0 +1,306 @@ +// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../npdu_tests/npdu_test_service.hpp" +#include "../npdu_tests/npdu_test_globals.hpp" + +#include +#include "../../implementation/configuration/include/configuration.hpp" +#include "../../implementation/configuration/include/configuration_impl.hpp" +#include "../../implementation/configuration/include/configuration_plugin.hpp" +#include "../../implementation/plugin/include/plugin_manager_impl.hpp" + + + +// this variable is set during compile time to create 4 service binaries of +// which each of them offers a service. +// Based on this number the service id, instance id and method ids are +// selected from the arrays defined in npdu_test_globals.hpp +#ifndef SERVICE_NUMBER +#define SERVICE_NUMBER 0 +#endif + +npdu_test_service::npdu_test_service(vsomeip::service_t _service_id, + vsomeip::instance_t _instance_id, + std::array _method_ids, + std::array _debounce_times, + std::array _max_retention_times) : + app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + method_ids_(_method_ids), + debounce_times_(_debounce_times), + max_retention_times_(_max_retention_times), + service_id_(_service_id), + instance_id_(_instance_id), + blocked_(false), + allowed_to_shutdown_(false), + number_of_received_messages_(0), + offer_thread_(std::bind(&npdu_test_service::run, this)), + shutdown_thread_(std::bind(&npdu_test_service::stop, this)) +{ + // init timepoints of last received message to one hour before now. + // needed that the first message which arrives isn't registered as undershot + // debounce time + for(auto &tp : timepoint_last_received_message_) { + tp = std::chrono::steady_clock::now() - std::chrono::hours(1); + } +} + +void npdu_test_service::init() +{ + std::lock_guard its_lock(mutex_); + + app_->init(); + + register_message_handler<0>(); + register_message_handler<1>(); + register_message_handler<2>(); + register_message_handler<3>(); + + app_->register_message_handler(service_id_, instance_id_, + npdu_test::NPDU_SERVICE_SHUTDOWNMETHOD_ID, + std::bind(&npdu_test_service::on_message_shutdown, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&npdu_test_service::on_state, this, + std::placeholders::_1)); +} + +template +void npdu_test_service::register_message_handler() { + app_->register_message_handler(service_id_, instance_id_, method_ids_[method_idx], + std::bind(&npdu_test_service::on_message, this, + std::placeholders::_1)); +} + +void npdu_test_service::start() +{ + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void npdu_test_service::stop() +{ + std::unique_lock its_lock(shutdown_mutex_); + while (!allowed_to_shutdown_) { + shutdown_condition_.wait(its_lock); + } + + VSOMEIP_INFO << "Stopping..."; + if (!undershot_debounce_times_.empty()) { + std::chrono::microseconds sum(0); + for (const auto t : undershot_debounce_times_) { + sum += t; + } + double average = static_cast(sum.count())/static_cast(undershot_debounce_times_.size()); + VSOMEIP_INFO << "[" + << std::setw(4) << std::setfill('0') << std::hex << service_id_ << "." + << std::setw(4) << std::setfill('0') << std::hex << instance_id_ << "]: " + << " Debounce time was undershot " << std::dec << undershot_debounce_times_.size() << "/" << number_of_received_messages_ + << "(" << std::setprecision(2) << (static_cast(undershot_debounce_times_.size()) / static_cast(number_of_received_messages_)) * 100.00 + << "%) on average: " << std::setprecision(4) << average << "µs"; + } + app_->unregister_message_handler(service_id_, instance_id_, method_ids_[0]); + app_->unregister_message_handler(service_id_, instance_id_, method_ids_[1]); + app_->unregister_message_handler(service_id_, instance_id_, method_ids_[2]); + app_->unregister_message_handler(service_id_, instance_id_, method_ids_[3]); + app_->unregister_message_handler(service_id_, + instance_id_, npdu_test::NPDU_SERVICE_SHUTDOWNMETHOD_ID); + app_->unregister_state_handler(); + offer_thread_.join(); + stop_offer(); + app_->stop(); +} + +void npdu_test_service::offer() +{ + app_->offer_service(service_id_, instance_id_); +} + +void npdu_test_service::stop_offer() +{ + app_->stop_offer_service(service_id_, instance_id_); +} + +void npdu_test_service::join_shutdown_thread() { + shutdown_thread_.join(); +} + +void npdu_test_service::on_state(vsomeip::state_type_e _state) +{ + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : + "deregistered."); + + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + if(!is_registered_) + { + std::lock_guard its_lock(mutex_); + is_registered_ = true; + blocked_ = true; + // "start" the run method thread + condition_.notify_one(); + } + } + else + { + is_registered_ = false; + } +} + +template +void npdu_test_service::check_times() { + std::lock_guard its_lock(timepoint_mutexes_[method_idx]); + // what time is it? + std::chrono::steady_clock::time_point now = + std::chrono::steady_clock::now(); + // how long is it since we received the last message? + std::chrono::nanoseconds time_since_last_message = + std::chrono::duration_cast( + now - timepoint_last_received_message_[method_idx]); + // store the current time + timepoint_last_received_message_[method_idx] = now; + + // check if the debounce time was undershot + if (time_since_last_message < debounce_times_[method_idx]) { + const auto time_undershot = std::chrono::duration_cast< + std::chrono::microseconds>(debounce_times_[method_idx] - time_since_last_message); + undershot_debounce_times_.push_back(time_undershot); + } + // check if maximum retention time was exceeded + // Disabled as it can't be guaranteed that exact every max retention time a + // message leaves the client endpoint. +#if 0 + if(time_since_last_message > max_retention_times_[method_idx]) { + VSOMEIP_ERROR << std::setw(4) << std::setfill('0') << std::hex + << service_id_ << ":" << std::setw(4) << std::setfill('0') + << std::hex << instance_id_ << ":" << std::setw(4) << std::setfill('0') + << std::hex << npdu_test::method_ids[SERVICE_NUMBER][method_idx] + << ": max_retention_time exceeded by: " << std::dec + << std::chrono::duration_cast( + time_since_last_message - max_retention_times_[method_idx]).count() + << "ms"; + GTEST_FATAL_FAILURE_("Max retention time was exceeded"); + } +#endif +} + +template +void npdu_test_service::on_message(const std::shared_ptr& _request) +{ + number_of_received_messages_++; + check_times(); + VSOMEIP_DEBUG << __func__ << " 0x" << std::setw(4) << std::setfill('0') << std::hex + << method_ids_[method_idx] << " payload size: " + << std::dec << _request->get_payload()->get_length(); + if(_request->get_message_type() != vsomeip::message_type_e::MT_REQUEST_NO_RETURN) { + std::shared_ptr its_response = + vsomeip::runtime::get()->create_response(_request); + app_->send(its_response); + } +} + +void npdu_test_service::on_message_shutdown( + const std::shared_ptr& _request) +{ + (void)_request; + VSOMEIP_DEBUG << "Number of received messages: " << number_of_received_messages_; + VSOMEIP_INFO << "Shutdown method was called, going down now."; + + std::lock_guard its_lock(shutdown_mutex_); + allowed_to_shutdown_ = true; + shutdown_condition_.notify_one(); +} + +void npdu_test_service::run() +{ + std::unique_lock its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); + + offer(); +} + +TEST(someip_npdu_test, offer_service_and_check_debounce_times) +{ + // get the configuration + std::shared_ptr its_configuration; + auto its_plugin = vsomeip::plugin_manager::get()->get_plugin( + vsomeip::plugin_type_e::CONFIGURATION_PLUGIN, VSOMEIP_CFG_LIBRARY); + if (its_plugin) { + auto its_config_plugin = std::dynamic_pointer_cast(its_plugin); + if (its_config_plugin) { + its_configuration = its_config_plugin->get_configuration("",""); + } + } + if (!its_configuration) { + ADD_FAILURE() << "No configuration object. " + "Either memory overflow or loading error detected!"; + return; + } + + // used to store the debounce times + std::array debounce_times; + std::array max_retention_times; + + + // query the debouncetimes from the configuration. We want to know the + // debounce times which the _clients_ of this service have to comply with + // when they send requests to this service. This is necessary as we want to + // check on the service side if they adhere to them. + // client one will only query method one, client two will only query method + // two and so on. + for(int i = 0; i < 4; i++) { + std::chrono::nanoseconds debounce(0), retention(0); + its_configuration->get_configured_timing_requests( + npdu_test::service_ids[SERVICE_NUMBER], + its_configuration->get_unicast_address().to_string(), + its_configuration->get_unreliable_port( + npdu_test::service_ids[SERVICE_NUMBER], + npdu_test::instance_ids[SERVICE_NUMBER]), + npdu_test::method_ids[SERVICE_NUMBER][i], + &debounce_times[i], + &max_retention_times[i]); + if (debounce == std::chrono::nanoseconds(VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO) && + retention == std::chrono::nanoseconds(VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO)) { + // no timings specified - checks in check_times() should never + // report an error in this case. + // set debounce time to 0 this can't be undershot + debounce_times[i] = std::chrono::nanoseconds(0); + // set max retention time its max, this won't be exceeded + max_retention_times[i] = std::chrono::nanoseconds::max(); + } + } + + npdu_test_service test_service( + npdu_test::service_ids[SERVICE_NUMBER], + npdu_test::instance_ids[SERVICE_NUMBER], + npdu_test::method_ids[SERVICE_NUMBER], + debounce_times, max_retention_times); + test_service.init(); + test_service.start(); + test_service.join_shutdown_thread(); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + int i = 1; + while (i < argc) + { + if(std::string("--help") == argv[i]) + { + VSOMEIP_INFO << "Parameters:\n" + << "--help: print this help"; + } + i++; + } + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/npdu_tests/npdu_test_service.hpp b/test/network_tests/npdu_tests/npdu_test_service.hpp new file mode 100644 index 0000000..bef0680 --- /dev/null +++ b/test/network_tests/npdu_tests/npdu_test_service.hpp @@ -0,0 +1,64 @@ +// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef NPDUTESTSERVICE_HPP_ +#define NPDUTESTSERVICE_HPP_ +#include + +#include + +#include +#include +#include +#include +#include +#include + +class npdu_test_service +{ +public: + npdu_test_service(vsomeip::service_t _service_id, + vsomeip::instance_t _instance_id, + std::array _method_ids, + std::array _debounce_times, + std::array _max_retention_times); + void init(); + void start(); + void stop(); + void offer(); + void stop_offer(); + void join_shutdown_thread(); + void on_state(vsomeip::state_type_e _state); + template void on_message(const std::shared_ptr &_request); + void on_message_shutdown(const std::shared_ptr &_request); + void run(); + +private: + template void check_times(); + template void register_message_handler(); + +private: + std::shared_ptr app_; + bool is_registered_; + std::array method_ids_; + std::array debounce_times_; + std::array max_retention_times_; + std::array timepoint_last_received_message_; + std::array timepoint_mutexes_; + std::deque undershot_debounce_times_; + vsomeip::service_t service_id_; + vsomeip::instance_t instance_id_; + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + std::mutex shutdown_mutex_; + std::condition_variable shutdown_condition_; + bool allowed_to_shutdown_; + std::uint32_t number_of_received_messages_; + std::thread offer_thread_; + std::thread shutdown_thread_; +}; + +#endif /* NPDUTESTSERVICE_HPP_ */ diff --git a/test/network_tests/npdu_tests/npdu_test_service_no_npdu_start.sh b/test/network_tests/npdu_tests/npdu_test_service_no_npdu_start.sh new file mode 100755 index 0000000..cf05aaa --- /dev/null +++ b/test/network_tests/npdu_tests/npdu_test_service_no_npdu_start.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the routing manager daemon and the +# services with one command. This is necessary as ctest - which is used to run +# the tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the routing +# manager daemon and the services and checks if all of them exit successfully. + +FAIL=0 + +start_services(){ + export VSOMEIP_CONFIGURATION=npdu_test_service_no_npdu.json + + # Start the routing manager daemon + export VSOMEIP_APPLICATION_NAME=npdu_test_routing_manager_daemon_service_side + ./npdu_test_rmd_service_side & + + # sleep 1 second to let the RMD startup. + sleep 1 + + # Start service 1 + export VSOMEIP_APPLICATION_NAME=npdu_test_service_one + ./npdu_test_service_1 $* & + + # Start service 2 + export VSOMEIP_APPLICATION_NAME=npdu_test_service_two + ./npdu_test_service_2 $* & + + # Start service 3 + export VSOMEIP_APPLICATION_NAME=npdu_test_service_three + ./npdu_test_service_3 $* & + + # Start service 4 + export VSOMEIP_APPLICATION_NAME=npdu_test_service_four + ./npdu_test_service_4 $* & +} + +wait_for_bg_processes(){ + # Wait until client and service are finished + for job in $(jobs -p) + do + # Fail gets incremented if one of the jobs exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) + done + + # Check if everything exited successfully + if [ $FAIL -eq 0 ] + then + echo "All services exited successfully" + else + echo "Something went wrong" + exit 1 + fi +} + +start_services +wait_for_bg_processes + +exit 0 diff --git a/test/network_tests/npdu_tests/npdu_test_service_npdu_start.sh b/test/network_tests/npdu_tests/npdu_test_service_npdu_start.sh new file mode 100755 index 0000000..0ca238b --- /dev/null +++ b/test/network_tests/npdu_tests/npdu_test_service_npdu_start.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the routing manager daemon and the +# services with one command. This is necessary as ctest - which is used to run +# the tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the routing +# manager daemon and the services and checks if all of them exit successfully. + +FAIL=0 + +start_services(){ + export VSOMEIP_CONFIGURATION=npdu_test_service_npdu.json + + # Start the routing manager daemon + export VSOMEIP_APPLICATION_NAME=npdu_test_routing_manager_daemon_service_side + ./npdu_test_rmd_service_side & + + # sleep 1 second to let the RMD startup. + sleep 1 + + # Start service 1 + export VSOMEIP_APPLICATION_NAME=npdu_test_service_one + ./npdu_test_service_1 $* & + + # Start service 2 + export VSOMEIP_APPLICATION_NAME=npdu_test_service_two + ./npdu_test_service_2 $* & + + # Start service 3 + export VSOMEIP_APPLICATION_NAME=npdu_test_service_three + ./npdu_test_service_3 $* & + + # Start service 4 + export VSOMEIP_APPLICATION_NAME=npdu_test_service_four + ./npdu_test_service_4 $* & +} + +wait_for_bg_processes(){ + # Wait until client and service are finished + for job in $(jobs -p) + do + # Fail gets incremented if one of the jobs exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) + done + + # Check if everything exited successfully + if [ $FAIL -eq 0 ] + then + echo "All services exited successfully" + else + echo "Something went wrong" + exit 1 + fi +} + +start_services +wait_for_bg_processes + +exit 0 diff --git a/test/network_tests/npdu_tests/npdu_test_starter.sh b/test/network_tests/npdu_tests/npdu_test_starter.sh new file mode 100755 index 0000000..51904c9 --- /dev/null +++ b/test/network_tests/npdu_tests/npdu_test_starter.sh @@ -0,0 +1,96 @@ +#!/bin/bash +# Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the routing manager daemon and the +# services with one command. This is necessary as ctest - which is used to run +# the tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the routing +# manager daemon and the services and checks if all of them exit successfully. + +FAIL=0 + +if [ $# -lt 2 ]; then + echo "Error: Please pass a protocol and communication mode to this script." + echo "Valid protocols are [UDP,TCP]." + echo "Valid communication modes are [sync, async]." + echo "For example $> $0 UDP sync" + exit 1; +fi + +start_services(){ + export VSOMEIP_CONFIGURATION=npdu_test_service_npdu.json + + # Start the routing manager daemon + export VSOMEIP_APPLICATION_NAME=npdu_test_routing_manager_daemon_service_side + ./npdu_test_rmd_service_side & + + # sleep 1 second to let the RMD startup. + sleep 1 + + # Start service 1 + export VSOMEIP_APPLICATION_NAME=npdu_test_service_one + ./npdu_test_service_1 $* & + + # Start service 2 + export VSOMEIP_APPLICATION_NAME=npdu_test_service_two + ./npdu_test_service_2 $* & + + # Start service 3 + export VSOMEIP_APPLICATION_NAME=npdu_test_service_three + ./npdu_test_service_3 $* & + + # Start service 4 + export VSOMEIP_APPLICATION_NAME=npdu_test_service_four + ./npdu_test_service_4 $* & +} + +wait_for_bg_processes(){ + # Wait until client and service are finished + for job in $(jobs -p) + do + # Fail gets incremented if one of the jobs exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) + done + + # Check if everything exited successfully + if [ $FAIL -eq 0 ] + then + echo "All services exited successfully" + else + echo "Something went wrong" + exit 1 + fi +} + + +start_services + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting magic cookies test on slave LXC" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./npdu_test_client_npdu_start.sh $*\"" & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./npdu_test_client_npdu_start.sh $*" & +else +sleep 1 +cat < should be rejected as there is already a service instance +# running in the network + +# Array for client pids +CLIENT_PIDS=() +export VSOMEIP_CONFIGURATION=offer_test_external_master.json +# start daemon +../../examples/routingmanagerd/./routingmanagerd & +PID_VSOMEIPD=$! +# Start the services +./offer_test_service 2 & +PID_SERVICE_TWO=$! +echo "SERVICE_TWO pid $PID_SERVICE_TWO" + +./offer_test_client SUBSCRIBE & +CLIENT_PIDS+=($!) +echo "client pid ${CLIENT_PIDS[0]}" + +sleep 1 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "Waiting for 5s" + sleep 5 + echo "starting offer test on slave LXC offer_test_external_slave_starter.sh" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./offer_test_external_slave_starter.sh\"" & + echo "remote ssh pid: $!" +elif [ ! -z "$USE_DOCKER" ]; then + echo "Waiting for 5s" + sleep 5 + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && sleep 10; ./offer_test_external_slave_starter.sh" & +else +cat < +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "offer_test_globals.hpp" + +class offer_test_big_sd_msg_client { +public: + offer_test_big_sd_msg_client(struct offer_test::service_info _service_info) : + service_info_(_service_info), + app_(vsomeip::runtime::get()->create_application("offer_test_big_sd_msg_client")), + wait_until_registered_(true), + wait_until_service_available_(true), + wait_until_subscribed_(true), + wait_for_stop_(true), + stop_thread_(std::bind(&offer_test_big_sd_msg_client::wait_for_stop, this)), + send_thread_(std::bind(&offer_test_big_sd_msg_client::send, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&offer_test_big_sd_msg_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, + std::bind(&offer_test_big_sd_msg_client::on_message, this, + std::placeholders::_1)); + + // register availability for all other services and request their event. + app_->register_availability_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, + std::bind(&offer_test_big_sd_msg_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3), 0x1, 0x1); + std::set its_eventgroups; + its_eventgroups.insert(offer_test::big_msg_eventgroup_id); + for (std::uint16_t s = 1; s <= offer_test::big_msg_number_services; s++) { + app_->request_service(s,0x1,0x1,0x1); + app_->request_event(s,0x1, offer_test::big_msg_event_id, + its_eventgroups, vsomeip::event_type_e::ET_EVENT, + vsomeip::reliability_type_e::RT_UNKNOWN); + app_->subscribe(s, 0x1,offer_test::big_msg_eventgroup_id, 0x1, + offer_test::big_msg_event_id); + services_available_subribed_[s] = std::make_pair(false,0); + app_->register_subscription_status_handler(s,0x1, + offer_test::big_msg_eventgroup_id, + offer_test::big_msg_event_id, + std::bind(&offer_test_big_sd_msg_client::subscription_status_changed, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); + } + app_->start(); + } + + ~offer_test_big_sd_msg_client() { + send_thread_.join(); + stop_thread_.join(); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_WARNING << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + VSOMEIP_DEBUG << "Service [" << std::setw(4) + << std::setfill('0') << std::hex << _service << "." << _instance + << "] is " << (_is_available ? "available":"not available") << "."; + + std::lock_guard its_lock(mutex_); + if(_is_available) { + auto found_service = services_available_subribed_.find(_service); + if (found_service != services_available_subribed_.end()) { + found_service->second.first = true; + if (std::all_of(services_available_subribed_.cbegin(), + services_available_subribed_.cend(), + [](const services_available_subribed_t::value_type& v) { + return v.second.first; + } + )) { + VSOMEIP_WARNING << "************************************************************"; + VSOMEIP_WARNING << "All services available!"; + VSOMEIP_WARNING << "************************************************************"; + wait_until_service_available_ = false; + condition_.notify_one(); + } + } + } + } + + void subscription_status_changed(const vsomeip::service_t _service, + const vsomeip::instance_t _instance, + const vsomeip::eventgroup_t _eventgroup, + const vsomeip::event_t _event, + const uint16_t _error) { + EXPECT_EQ(0x1, _instance); + EXPECT_EQ(offer_test::big_msg_eventgroup_id, _eventgroup); + EXPECT_EQ(offer_test::big_msg_event_id, _event); + VSOMEIP_DEBUG << "Service [" << std::setw(4) + << std::setfill('0') << std::hex << _service << "." << _instance + << "] has " << (!_error ? "sent subscribe ack":" sent subscribe_nack") << "."; + if (_error == 0x0 /*OK*/) { + + std::lock_guard its_lock(mutex_); + auto found_service = services_available_subribed_.find(_service); + if (found_service != services_available_subribed_.end()) { + found_service->second.second++; + if (found_service->second.second > 1) { + ADD_FAILURE() << "Registered subscription status handler was " + "called " << std::dec << found_service->second.second + << " times for service: " << std::hex + << found_service->first; + } + if (std::all_of(services_available_subribed_.cbegin(), + services_available_subribed_.cend(), + [](const services_available_subribed_t::value_type& v) { + return v.second.second == 1; + } + )) { + VSOMEIP_WARNING << "************************************************************"; + VSOMEIP_WARNING << "All subscription were acknowledged!"; + VSOMEIP_WARNING << "************************************************************"; + wait_until_subscribed_ = false; + condition_.notify_one(); + } + } + } + }; + + void on_message(const std::shared_ptr &_message) { + if (_message->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + on_response(_message); + } + } + + void on_response(const std::shared_ptr &_message) { + EXPECT_EQ(0x1, _message->get_service()); + EXPECT_EQ(service_info_.shutdown_method_id, _message->get_method()); + EXPECT_EQ(0x1, _message->get_instance()); + if(service_info_.shutdown_method_id == _message->get_method()) { + std::lock_guard its_lock(stop_mutex_); + wait_for_stop_ = false; + VSOMEIP_INFO << "going down"; + stop_condition_.notify_one(); + } + } + + void send() { + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + while (wait_until_service_available_) { + condition_.wait(its_lock); + } + + while (wait_until_subscribed_) { + condition_.wait(its_lock); + } + + std::this_thread::sleep_for(std::chrono::seconds(5)); + std::shared_ptr its_req = vsomeip::runtime::get()->create_request(); + its_req->set_service(1); + its_req->set_instance(1); + its_req->set_interface_version(0x1); + its_req->set_method(service_info_.shutdown_method_id); + app_->send(its_req); + } + + void wait_for_stop() { + std::unique_lock its_lock(stop_mutex_); + while (wait_for_stop_) { + stop_condition_.wait(its_lock); + } + VSOMEIP_INFO << "going down"; + app_->clear_all_handler(); + app_->stop(); + } + +private: + struct offer_test::service_info service_info_; + std::shared_ptr app_; + + bool wait_until_registered_; + bool wait_until_service_available_; + bool wait_until_subscribed_; + std::mutex mutex_; + std::condition_variable condition_; + + bool wait_for_stop_; + std::mutex stop_mutex_; + std::condition_variable stop_condition_; + + typedef std::map> services_available_subribed_t; + services_available_subribed_t services_available_subribed_; + std::thread stop_thread_; + std::thread send_thread_; +}; + +TEST(someip_offer_test_big_sd_msg, subscribe_or_call_method_at_service) +{ + offer_test_big_sd_msg_client its_sample(offer_test::service); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/offer_tests/offer_test_big_sd_msg_service.cpp b/test/network_tests/offer_tests/offer_test_big_sd_msg_service.cpp new file mode 100644 index 0000000..1cf52f9 --- /dev/null +++ b/test/network_tests/offer_tests/offer_test_big_sd_msg_service.cpp @@ -0,0 +1,172 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "offer_test_globals.hpp" + +class offer_test_big_sd_msg_service { +public: + offer_test_big_sd_msg_service(struct offer_test::service_info _service_info) : + service_info_(_service_info), + // service with number 1 uses "routingmanagerd" as application name + // this way the same json file can be reused for all local tests + // including the ones with routingmanagerd + app_(vsomeip::runtime::get()->create_application("offer_test_big_sd_msg_service")), + wait_until_registered_(true), + wait_until_client_subscribed_to_all_services_(true), + shutdown_method_called_(false), + offer_thread_(std::bind(&offer_test_big_sd_msg_service::run, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&offer_test_big_sd_msg_service::on_state, this, + std::placeholders::_1)); + + // offer field + std::set its_eventgroups; + its_eventgroups.insert(offer_test::big_msg_eventgroup_id); + for (std::uint16_t s = 1; s <= offer_test::big_msg_number_services; s++) { + app_->offer_event(s, 0x1, + offer_test::big_msg_event_id, its_eventgroups, + vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + app_->register_subscription_handler(s, 0x1, offer_test::big_msg_eventgroup_id, + std::bind(&offer_test_big_sd_msg_service::on_subscription, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4, s)); + subscriptions_[s] = 0; + } + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, service_info_.shutdown_method_id, + std::bind(&offer_test_big_sd_msg_service::on_shutdown_method_called, this, + std::placeholders::_1)); + + + app_->start(); + } + + ~offer_test_big_sd_msg_service() { + offer_thread_.join(); + } + + void offer() { + for (std::uint16_t s = 1; s <= offer_test::big_msg_number_services; s++) { + app_->offer_service(s,0x1,0x1,0x1); + } + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + bool on_subscription(vsomeip::client_t _client, + std::uint32_t _uid, std::uint32_t _gid, + bool _subscribed, + vsomeip::service_t _service) { + (void)_client; + (void)_uid; + (void)_gid; + if (_subscribed) { + subscriptions_[_service]++; + EXPECT_EQ(1u, subscriptions_[_service]); + if (std::all_of(subscriptions_.begin(), subscriptions_.end(), [&](const subscriptions_t::value_type& v){ + return v.second == 1; + })) { + std::lock_guard its_lock(mutex_); + wait_until_client_subscribed_to_all_services_ = false; + VSOMEIP_WARNING << "************************************************************"; + VSOMEIP_WARNING << "Client subscribed to all services!"; + VSOMEIP_WARNING << "************************************************************"; + condition_.notify_one(); + } + } + + return true; + } + + void on_shutdown_method_called(const std::shared_ptr &_message) { + app_->send(vsomeip::runtime::get()->create_response(_message)); + std::this_thread::sleep_for(std::chrono::seconds(1)); + VSOMEIP_WARNING << "************************************************************"; + VSOMEIP_WARNING << "Shutdown method called -> going down!"; + VSOMEIP_WARNING << "************************************************************"; + shutdown_method_called_ = true; + for (std::uint16_t s = 1; s <= offer_test::big_msg_number_services; s++) { + app_->stop_offer_service(s,0x1,0x1,0x1); + } + app_->clear_all_handler(); + app_->stop(); + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + + while (wait_until_client_subscribed_to_all_services_) { + condition_.wait(its_lock); + } + } + +private: + struct offer_test::service_info service_info_; + std::shared_ptr app_; + + bool wait_until_registered_; + bool wait_until_client_subscribed_to_all_services_; + std::mutex mutex_; + std::condition_variable condition_; + std::atomic shutdown_method_called_; + typedef std::map subscriptions_t; + subscriptions_t subscriptions_; + std::thread offer_thread_; +}; + +TEST(someip_offer_test_big_sd_msg, notify_increasing_counter) +{ + offer_test_big_sd_msg_service its_sample(offer_test::service); +} + + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/offer_tests/offer_test_big_sd_msg_slave_starter.sh b/test/network_tests/offer_tests/offer_test_big_sd_msg_slave_starter.sh new file mode 100755 index 0000000..5f69c30 --- /dev/null +++ b/test/network_tests/offer_tests/offer_test_big_sd_msg_slave_starter.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 +# Rejecting offer for which there is already a remote offer: +# * start daemon +# * start application which offers service +# * start daemon remotely +# * start same application which offers the same service again remotely +# -> should be rejected as there is already a service instance +# running in the network + +export VSOMEIP_CONFIGURATION=offer_test_big_sd_msg_slave.json +# start daemon +../../examples/routingmanagerd/./routingmanagerd & +PID_VSOMEIPD=$! +sleep 1 +# Start the services +./offer_test_big_sd_msg_service & +PID_SERVICE_TWO=$! +sleep 1 + +# Wait until all clients and services are finished +for job in $PID_SERVICE_TWO +do + # Fail gets incremented if a client exits with a non-zero exit code + wait $job || FAIL=$(($FAIL+1)) +done + +# kill the services +kill $PID_VSOMEIPD +sleep 1 + + + +# Check if everything went well +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/offer_tests/offer_test_client.cpp b/test/network_tests/offer_tests/offer_test_client.cpp new file mode 100644 index 0000000..e8ad09f --- /dev/null +++ b/test/network_tests/offer_tests/offer_test_client.cpp @@ -0,0 +1,288 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#ifdef ANDROID +#include "../../implementation/configuration/include/internal_android.hpp" +#else +#include "../../implementation/configuration/include/internal.hpp" +#endif // ANDROID + +#include "offer_test_globals.hpp" + +enum operation_mode_e { + SUBSCRIBE, + METHODCALL +}; + +class offer_test_client { +public: + offer_test_client(struct offer_test::service_info _service_info, operation_mode_e _mode) : + service_info_(_service_info), + operation_mode_(_mode), + app_(vsomeip::runtime::get()->create_application("offer_test_client")), + wait_until_registered_(true), + wait_until_service_available_(true), + wait_for_stop_(true), + last_received_counter_(0), + last_received_response_(std::chrono::steady_clock::now()), + number_received_responses_(0), + stop_thread_(std::bind(&offer_test_client::wait_for_stop, this)), + send_thread_(std::bind(&offer_test_client::send, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&offer_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, + std::bind(&offer_test_client::on_message, this, + std::placeholders::_1)); + + // register availability for all other services and request their event. + app_->register_availability_handler(service_info_.service_id, + service_info_.instance_id, + std::bind(&offer_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + app_->request_service(service_info_.service_id, + service_info_.instance_id); + + if (operation_mode_ == operation_mode_e::SUBSCRIBE) { + std::set its_eventgroups; + its_eventgroups.insert(service_info_.eventgroup_id); + app_->request_event(service_info_.service_id, + service_info_.instance_id, service_info_.event_id, + its_eventgroups, vsomeip::event_type_e::ET_EVENT, + vsomeip::reliability_type_e::RT_BOTH); + + app_->subscribe(service_info_.service_id, service_info_.instance_id, + service_info_.eventgroup_id, vsomeip::DEFAULT_MAJOR); + } + + app_->start(); + } + + ~offer_test_client() { + send_thread_.join(); + stop_thread_.join(); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + VSOMEIP_INFO << "Service [" << std::setw(4) + << std::setfill('0') << std::hex << _service << "." << _instance + << "] is " << (_is_available ? "available":"not available") << "."; + std::lock_guard its_lock(mutex_); + if(_is_available) { + wait_until_service_available_ = false; + condition_.notify_one(); + } else { + wait_until_service_available_ = true; + condition_.notify_one(); + } + } + + void on_message(const std::shared_ptr &_message) { + if(_message->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + on_notification(_message); + } else if (_message->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + on_response(_message); + } + } + + void on_notification(const std::shared_ptr &_message) { + std::shared_ptr its_payload(_message->get_payload()); + EXPECT_EQ(4u, its_payload->get_length()); + vsomeip::byte_t *d = its_payload->get_data(); + static std::uint32_t number_received_notifications(0); + std::uint32_t counter(0); + counter |= static_cast(d[0] << 24); + counter |= static_cast(d[0] << 16); + counter = counter | static_cast((d[2] << 8)); + counter = counter | static_cast(d[3]); + + VSOMEIP_DEBUG + << "Received a notification with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_session() << "] from Service/Method [" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_service() << "/" << std::setw(4) << std::setfill('0') + << std::hex << _message->get_method() <<"] got:" << std::dec << counter; + + ASSERT_GT(counter, last_received_counter_); + last_received_counter_ = counter; + ++number_received_notifications; + + if(number_received_notifications >= 250) { + std::lock_guard its_lock(stop_mutex_); + wait_for_stop_ = false; + VSOMEIP_INFO << "going down"; + stop_condition_.notify_one(); + } + } + + void on_response(const std::shared_ptr &_message) { + ++number_received_responses_; + static bool first(true); + if (first) { + first = false; + last_received_response_ = std::chrono::steady_clock::now(); + return; + } + EXPECT_EQ(service_info_.service_id, _message->get_service()); + EXPECT_EQ(service_info_.method_id, _message->get_method()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + ASSERT_LT(std::chrono::duration_cast( + std::chrono::steady_clock::now() - last_received_response_).count(), + (std::chrono::milliseconds(VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT) + + std::chrono::milliseconds(1000)).count()); + last_received_response_ = std::chrono::steady_clock::now(); + std::cout << "."; + std::cout.flush(); + } + + void send() { + if (operation_mode_ != operation_mode_e::METHODCALL) { + return; + } + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + while (wait_until_service_available_) { + condition_.wait(its_lock); + } + its_lock.unlock(); + its_lock.release(); + + for (int var = 0; var < offer_test::number_of_messages_to_send; ++var) { + bool send(false); + { + std::lock_guard its_lock(mutex_); + send = !wait_until_service_available_; + } + if (send) { + std::shared_ptr its_req = vsomeip::runtime::get()->create_request(); + its_req->set_service(service_info_.service_id); + its_req->set_instance(service_info_.instance_id); + its_req->set_method(service_info_.method_id); + app_->send(its_req); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } else { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + { + std::lock_guard its_lock(stop_mutex_); + wait_for_stop_ = false; + VSOMEIP_INFO << "going down. Sent " << offer_test::number_of_messages_to_send + << " requests and received " << number_received_responses_ + << " responses"; + stop_condition_.notify_one(); + } + } + + void wait_for_stop() { + std::unique_lock its_lock(stop_mutex_); + while (wait_for_stop_) { + stop_condition_.wait(its_lock); + } + VSOMEIP_INFO << "going down"; + app_->clear_all_handler(); + app_->stop(); + } + +private: + struct offer_test::service_info service_info_; + operation_mode_e operation_mode_; + std::shared_ptr app_; + + bool wait_until_registered_; + bool wait_until_service_available_; + std::mutex mutex_; + std::condition_variable condition_; + + bool wait_for_stop_; + std::mutex stop_mutex_; + std::condition_variable stop_condition_; + + std::uint32_t last_received_counter_; + std::chrono::steady_clock::time_point last_received_response_; + std::atomic number_received_responses_; + std::thread stop_thread_; + std::thread send_thread_; +}; + +static operation_mode_e passed_mode = operation_mode_e::SUBSCRIBE; + +TEST(someip_offer_test, subscribe_or_call_method_at_service) +{ + offer_test_client its_sample(offer_test::service, passed_mode); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a operation mode, like: " << argv[0] << " SUBSCRIBE" << std::endl; + std::cerr << "Valid operation modes are SUBSCRIBE and METHODCALL" << std::endl; + return 1; + } + + if (std::string("SUBSCRIBE") == std::string(argv[1])) { + passed_mode = operation_mode_e::SUBSCRIBE; + } else if (std::string("METHODCALL") == std::string(argv[1])) { + passed_mode = operation_mode_e::METHODCALL; + } else { + std::cerr << "Wrong operation mode passed, exiting" << std::endl; + std::cerr << "Please specify a operation mode, like: " << argv[0] << " SUBSCRIBE" << std::endl; + std::cerr << "Valid operation modes are SUBSCRIBE and METHODCALL" << std::endl; + return 1; + } + +#if 0 + if (argc >= 4 && std::string("SAME_SERVICE_ID") == std::string(argv[3])) { + use_same_service_id = true; + } else { + use_same_service_id = false; + } +#endif + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/offer_tests/offer_test_external_sd_msg_sender.cpp b/test/network_tests/offer_tests/offer_test_external_sd_msg_sender.cpp new file mode 100644 index 0000000..db9446e --- /dev/null +++ b/test/network_tests/offer_tests/offer_test_external_sd_msg_sender.cpp @@ -0,0 +1,78 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include + +#include + +static char* passed_address; + +TEST(someip_offer_test, send_offer_service_sd_message) +{ + try { +#if VSOMEIP_BOOST_VERSION < 106600 + boost::asio::io_service io; +#else + boost::asio::io_context io; +#endif + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(passed_address)), + 30490); + boost::asio::ip::udp::socket udp_socket(io, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + std::uint8_t its_offer_service_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x3c, + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, + 0x01, 0x00, 0x00, 0x20, + 0x11, 0x11, 0x00, 0x01, + 0x00, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, + 0x00, 0x09, 0x04, 0x00, + 0x0a, 0x00, 0x03, 0x01, + 0x00, 0x06, 0x9c, 0x41, + 0x00, 0x09, 0x04, 0x00, + 0x0a, 0x00, 0x03, 0x7D, // slave address + 0x00, 0x11, 0x75, 0x31 + }; + for (int var = 0; var < 15; ++var) { + udp_socket.send_to(boost::asio::buffer(its_offer_service_message), target_sd); + ++its_offer_service_message[11]; + } + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x11, 0x11, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x01, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(passed_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); + } catch (...) { + ASSERT_FALSE(true); + } +} + + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cout << "Please pass an target IP address to this binary like: " + << argv[0] << " 10.0.3.1" << std::endl; + exit(1); + } + passed_address = argv[1]; + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/offer_tests/offer_test_external_slave_starter.sh b/test/network_tests/offer_tests/offer_test_external_slave_starter.sh new file mode 100755 index 0000000..511bed1 --- /dev/null +++ b/test/network_tests/offer_tests/offer_test_external_slave_starter.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 +# Rejecting offer for which there is already a remote offer: +# * start daemon +# * start application which offers service +# * start daemon remotely +# * start same application which offers the same service again remotely +# -> should be rejected as there is already a service instance +# running in the network + +export VSOMEIP_CONFIGURATION=offer_test_external_slave.json +# start daemon +../../examples/routingmanagerd/routingmanagerd & +PID_VSOMEIPD=$! +sleep 1 +# Start the services +./offer_test_service_external 2 & +PID_SERVICE_TWO=$! +sleep 1 + +# Wait until all clients and services are finished +for job in $PID_SERVICE_TWO +do + # Fail gets incremented if a client exits with a non-zero exit code + wait $job || FAIL=$(($FAIL+1)) +done + +# kill the services +kill $PID_VSOMEIPD +sleep 1 + + + +# Check if everything went well +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/offer_tests/offer_test_globals.hpp b/test/network_tests/offer_tests/offer_test_globals.hpp new file mode 100644 index 0000000..ba69886 --- /dev/null +++ b/test/network_tests/offer_tests/offer_test_globals.hpp @@ -0,0 +1,29 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef OFFER_TEST_GLOBALS_HPP_ +#define OFFER_TEST_GLOBALS_HPP_ + +namespace offer_test { + +struct service_info { + vsomeip::service_t service_id; + vsomeip::instance_t instance_id; + vsomeip::method_t method_id; + vsomeip::event_t event_id; + vsomeip::eventgroup_t eventgroup_id; + vsomeip::method_t shutdown_method_id; +}; + +struct service_info service = { 0x1111, 0x1, 0x1111, 0x1111, 0x1000, 0x1404 }; + +static constexpr int number_of_messages_to_send = 150; + +static constexpr std::uint16_t big_msg_number_services = 300; +static constexpr vsomeip::event_t big_msg_event_id = 0x8000; +static constexpr vsomeip::eventgroup_t big_msg_eventgroup_id = 0x1; +} + +#endif /* OFFER_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/offer_tests/offer_test_local.json b/test/network_tests/offer_tests/offer_test_local.json new file mode 100644 index 0000000..be8aa09 --- /dev/null +++ b/test/network_tests/offer_tests/offer_test_local.json @@ -0,0 +1,20 @@ +{ + "unicast":"127.0.0.1", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "routing":"routingmanagerd", + "service-discovery": + { + "enable":"false" + } +} + diff --git a/test/network_tests/offer_tests/offer_test_local_starter.sh b/test/network_tests/offer_tests/offer_test_local_starter.sh new file mode 100755 index 0000000..6c91a6d --- /dev/null +++ b/test/network_tests/offer_tests/offer_test_local_starter.sh @@ -0,0 +1,298 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +FAIL=0 + +cat < should be +# rejected and an error message should be printed. +# * Message exchange with client application should not be interrupted. + +# Array for client pids +CLIENT_PIDS=() +export VSOMEIP_CONFIGURATION=offer_test_local.json +# Start the services +./offer_test_service 1 & +PID_SERVICE_ONE=$! +./offer_test_client SUBSCRIBE & +CLIENT_PIDS+=($!) +./offer_test_client SUBSCRIBE & +CLIENT_PIDS+=($!) + +./offer_test_service 2 & +PID_SERVICE_TWO=$! + +# Wait until all clients are finished +for job in ${CLIENT_PIDS[*]} +do + # Fail gets incremented if a client exits with a non-zero exit code + wait $job || FAIL=$(($FAIL+1)) +done + +# kill the services +kill $PID_SERVICE_TWO +kill $PID_SERVICE_ONE +sleep 1 + + +cat < should be +# rejected and an error message should be printed. +# * Message exchange with client application should not be interrupted. + +# Array for client pids +CLIENT_PIDS=() +export VSOMEIP_CONFIGURATION=offer_test_local.json +# start daemon +../../examples/routingmanagerd/./routingmanagerd & +PID_VSOMEIPD=$! + +# Start the services +./offer_test_service 2 & +PID_SERVICE_TWO=$! +./offer_test_client SUBSCRIBE & +CLIENT_PIDS+=($!) +./offer_test_client SUBSCRIBE & +CLIENT_PIDS+=($!) + +./offer_test_service 3 & +PID_SERVICE_THREE=$! + +# Wait until all clients are finished +for job in ${CLIENT_PIDS[*]} +do + # Fail gets incremented if a client exits with a non-zero exit code + wait $job || FAIL=$(($FAIL+1)) +done + +# kill the services +kill $PID_SERVICE_THREE +kill $PID_SERVICE_TWO +sleep 1 +kill $PID_VSOMEIPD +sleep 1 + + +cat < should be +# accepted. +# * start another client which exchanges messages with the service +# * Client should now communicate with new offerer. + +# Array for client pids +CLIENT_PIDS=() +export VSOMEIP_CONFIGURATION=offer_test_local.json +# start daemon +../../examples/routingmanagerd/./routingmanagerd & +PID_VSOMEIPD=$! +# Start the service +./offer_test_service 2 & +PID_SERVICE_TWO=$! + +# Start a client +./offer_test_client METHODCALL & +CLIENT_PIDS+=($!) + +# Kill the service +sleep 1 +kill -KILL $PID_SERVICE_TWO + +# reoffer the service +./offer_test_service 3 & +PID_SERVICE_THREE=$! + +# Start another client +./offer_test_client METHODCALL & +CLIENT_PIDS+=($!) + +# Wait until all clients are finished +for job in ${CLIENT_PIDS[*]} +do + # Fail gets incremented if a client exits with a non-zero exit code + wait $job || FAIL=$(($FAIL+1)) +done + +# kill the services +kill $PID_SERVICE_THREE +kill $PID_VSOMEIPD +sleep 1 + +cat < should be +# marked as PENDING_OFFER and a ping should be sent to the paused +# application. +# * After the timeout passed the new offer should be accepted. +# * start client which exchanges messages with the service +# * Client should now communicate with new offerer. + +# Array for client pids +CLIENT_PIDS=() +export VSOMEIP_CONFIGURATION=offer_test_local.json +# start daemon +../../examples/routingmanagerd/./routingmanagerd & +PID_VSOMEIPD=$! +# Start the service +./offer_test_service 2 & +PID_SERVICE_TWO=$! + +# Start a client +./offer_test_client METHODCALL & +CLIENT_PIDS+=($!) + +# Pause the service +sleep 1 +kill -STOP $PID_SERVICE_TWO + +# reoffer the service +./offer_test_service 3 & +PID_SERVICE_THREE=$! + +# Start another client +./offer_test_client METHODCALL & +CLIENT_PIDS+=($!) + +# Wait until all clients are finished +for job in ${CLIENT_PIDS[*]} +do + # Fail gets incremented if a client exits with a non-zero exit code + wait $job || FAIL=$(($FAIL+1)) +done + +# kill the services +kill -CONT $PID_SERVICE_TWO +kill $PID_SERVICE_TWO +kill $PID_SERVICE_THREE +kill $PID_VSOMEIPD +sleep 1 + +cat < should be +# marked as PENDING_OFFER and a ping should be sent to the paused +# application. +# * start application which offers the same service again -> should be +# rejected as there is already a PENDING_OFFER pending. +# * After the timeout passed the new offer should be accepted. +# * start client which exchanges messages with the service +# * Client should now communicate with new offerer. + +# Array for client pids +CLIENT_PIDS=() +export VSOMEIP_CONFIGURATION=offer_test_local.json +# start daemon +../../examples/routingmanagerd/./routingmanagerd & +PID_VSOMEIPD=$! +# Start the service +./offer_test_service 2 & +PID_SERVICE_TWO=$! + +# Start a client +./offer_test_client METHODCALL & +CLIENT_PIDS+=($!) + +# Pause the service +sleep 1 +kill -STOP $PID_SERVICE_TWO + +# reoffer the service +./offer_test_service 3 & +PID_SERVICE_THREE=$! + +# reoffer the service again to provoke rejecting as there is +# already a pending offer +./offer_test_service 4 & +PID_SERVICE_FOUR=$! + +# Start another client +./offer_test_client METHODCALL & +CLIENT_PIDS+=($!) + +# Wait until all clients are finished +for job in ${CLIENT_PIDS[*]} +do + # Fail gets incremented if a client exits with a non-zero exit code + wait $job || FAIL=$(($FAIL+1)) +done + +# kill the services +kill -CONT $PID_SERVICE_TWO +kill $PID_SERVICE_TWO +kill $PID_SERVICE_THREE +kill $PID_SERVICE_FOUR +kill $PID_VSOMEIPD + + +# Check if everything went well +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/offer_tests/offer_test_service.cpp b/test/network_tests/offer_tests/offer_test_service.cpp new file mode 100644 index 0000000..c160a6f --- /dev/null +++ b/test/network_tests/offer_tests/offer_test_service.cpp @@ -0,0 +1,171 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "offer_test_globals.hpp" + +static std::string service_number; + +class offer_test_service { +public: + offer_test_service(struct offer_test::service_info _service_info) : + service_info_(_service_info), + // service with number 1 uses "routingmanagerd" as application name + // this way the same json file can be reused for all local tests + // including the ones with routingmanagerd + app_(vsomeip::runtime::get()->create_application( + (service_number == "1") ? "routingmanagerd" : + "offer_test_service" + service_number)), + counter_(0), + wait_until_registered_(true), + shutdown_method_called_(false), + offer_thread_(std::bind(&offer_test_service::run, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&offer_test_service::on_state, this, + std::placeholders::_1)); + + // offer field + std::set its_eventgroups; + its_eventgroups.insert(service_info_.eventgroup_id); + app_->offer_event(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_eventgroups, + vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_BOTH); + + inc_counter_and_notify(); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.method_id, + std::bind(&offer_test_service::on_request, this, + std::placeholders::_1)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.shutdown_method_id, + std::bind(&offer_test_service::on_shutdown_method_called, this, + std::placeholders::_1)); + app_->start(); + } + + ~offer_test_service() { + offer_thread_.join(); + } + + void offer() { + app_->offer_service(service_info_.service_id, service_info_.instance_id); + // this is allowed + app_->offer_service(service_info_.service_id, service_info_.instance_id); + // this is not allowed and will be rejected + app_->offer_service(service_info_.service_id, service_info_.instance_id, 33, 4711); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_request(const std::shared_ptr &_message) { + app_->send(vsomeip::runtime::get()->create_response(_message)); + } + + void on_shutdown_method_called(const std::shared_ptr &_message) { + (void)_message; + shutdown_method_called_ = true; + // this is will trigger a warning + app_->stop_offer_service(service_info_.service_id, service_info_.instance_id, 44, 4711); + app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); + app_->clear_all_handler(); + app_->stop(); + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Notifying"; + while(!shutdown_method_called_) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + inc_counter_and_notify(); + } + } + + void inc_counter_and_notify() { + ++counter_; + // set value to field + const std::shared_ptr its_payload(vsomeip::runtime::get()->create_payload()); + std::vector its_data; + its_data.push_back(static_cast((counter_ & 0xFF000000) >> 24)); + its_data.push_back(static_cast((counter_ & 0xFF0000) >> 16)); + its_data.push_back(static_cast((counter_ & 0xFF00) >> 8)); + its_data.push_back(static_cast((counter_ & 0xFF))); + its_payload->set_data(its_data); + app_->notify(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_payload); + } + +private: + struct offer_test::service_info service_info_; + std::shared_ptr app_; + std::uint32_t counter_; + + bool wait_until_registered_; + std::mutex mutex_; + std::condition_variable condition_; + std::atomic shutdown_method_called_; + std::thread offer_thread_; +}; + +TEST(someip_offer_test, notify_increasing_counter) +{ + offer_test_service its_sample(offer_test::service); +} + + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a service number, like: " << argv[0] << " 2" << std::endl; + return 1; + } + + service_number = std::string(argv[1]); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/offer_tests/offer_test_service_external.cpp b/test/network_tests/offer_tests/offer_test_service_external.cpp new file mode 100644 index 0000000..7cd8ad8 --- /dev/null +++ b/test/network_tests/offer_tests/offer_test_service_external.cpp @@ -0,0 +1,155 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "offer_test_globals.hpp" + +static std::string service_number; + +class offer_test_service { +public: + offer_test_service(struct offer_test::service_info _service_info) : + service_info_(_service_info), + // service with number 1 uses "routingmanagerd" as application name + // this way the same json file can be reused for all local tests + // including the ones with routingmanagerd + app_(vsomeip::runtime::get()->create_application( + (service_number == "1") ? "routingmanagerd" : + "offer_test_service" + service_number)), + wait_until_registered_(true), + wait_until_service_available_(true), + offer_thread_(std::bind(&offer_test_service::run, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&offer_test_service::on_state, this, + std::placeholders::_1)); + + app_->register_availability_handler(service_info_.service_id, + service_info_.instance_id, + std::bind(&offer_test_service::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + app_->request_service(service_info_.service_id, + service_info_.instance_id); + app_->start(); + } + + ~offer_test_service() { + offer_thread_.join(); + } + + void offer() { + app_->offer_service(service_info_.service_id, service_info_.instance_id); + // this is allowed + app_->offer_service(service_info_.service_id, service_info_.instance_id); + // this is not allowed and will be rejected + app_->offer_service(service_info_.service_id, service_info_.instance_id, 33, 4711); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + VSOMEIP_INFO << "Service [" << std::setw(4) + << std::setfill('0') << std::hex << _service << "." << _instance + << "] is " << (_is_available ? "available":"not available") << "."; + std::lock_guard its_lock(mutex_); + if(_is_available) { + wait_until_service_available_ = false; + condition_.notify_one(); + } else { + wait_until_service_available_ = true; + condition_.notify_one(); + } + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + { + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + + while(wait_until_service_available_) { + condition_.wait(its_lock); + } + } + + std::this_thread::sleep_for(std::chrono::seconds(1)); + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Calling stop method"; + std::shared_ptr msg(vsomeip::runtime::get()->create_request()); + msg->set_service(service_info_.service_id); + msg->set_instance(service_info_.instance_id); + msg->set_method(service_info_.shutdown_method_id); + msg->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + app_->send(msg); + std::this_thread::sleep_for(std::chrono::seconds(2)); + app_->clear_all_handler(); + app_->stop(); + } + +private: + struct offer_test::service_info service_info_; + std::shared_ptr app_; + + bool wait_until_registered_; + bool wait_until_service_available_; + std::mutex mutex_; + std::condition_variable condition_; + std::thread offer_thread_; +}; + +TEST(someip_offer_test, notify_increasing_counter) +{ + offer_test_service its_sample(offer_test::service); +} + + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a service number, like: " << argv[0] << " 2" << std::endl; + return 1; + } + + service_number = std::string(argv[1]); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/offered_services_info_test/offered_services_info_test_client.cpp b/test/network_tests/offered_services_info_test/offered_services_info_test_client.cpp new file mode 100644 index 0000000..4a2ce0e --- /dev/null +++ b/test/network_tests/offered_services_info_test/offered_services_info_test_client.cpp @@ -0,0 +1,333 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#ifdef ANDROID +#include "../../implementation/configuration/include/internal_android.hpp" +#else +#include "../../implementation/configuration/include/internal.hpp" +#endif + +#include "offered_services_info_test_globals.hpp" + +enum operation_mode_e { + SUBSCRIBE, + METHODCALL +}; + +std::map> all_offered_services; +std::map> local_offered_services; +std::map> remote_offered_services; + +class offered_services_info_test_client { +public: + offered_services_info_test_client(struct offer_test::service_info _service_info,offer_test::service_info _remote_service_info, operation_mode_e _mode) : + service_info_(_service_info), + remote_service_info_(_remote_service_info), + operation_mode_(_mode), + app_(vsomeip::runtime::get()->create_application("offered_services_info_test_client")), + wait_until_registered_(true), + wait_until_service_available_(true), + wait_for_stop_(true), + last_received_response_(std::chrono::steady_clock::now()), + number_received_responses_(0), + stop_thread_(std::bind(&offered_services_info_test_client::wait_for_stop, this)), + test_offered_services_thread_(std::bind(&offered_services_info_test_client::test_offered_services, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + + local_offered_services[service_info_.service_id].insert(service_info_.instance_id); + all_offered_services[service_info_.service_id].insert(service_info_.instance_id); + + local_offered_services[service_info_.service_id].insert((vsomeip::instance_t)(service_info_.instance_id + 1)); + all_offered_services[service_info_.service_id].insert((vsomeip::instance_t)(service_info_.instance_id + 1)); + + // offer remote service ID 0x2222 instance ID 0x2 (port configuration added to json file) + remote_offered_services[remote_service_info_.service_id].insert(remote_service_info_.instance_id); + all_offered_services[remote_service_info_.service_id].insert(remote_service_info_.instance_id); + + remote_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 1)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 1)); + all_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 1)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 1)); + + remote_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 2)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 2)); + all_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 2)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 2)); + + app_->register_state_handler( + std::bind(&offered_services_info_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, + std::bind(&offered_services_info_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, + std::bind(&offered_services_info_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + // request all services + app_->request_service(service_info_.service_id, service_info_.instance_id); + app_->request_service(service_info_.service_id, vsomeip::instance_t(service_info_.instance_id + 1)); + app_->request_service(remote_service_info_.service_id, remote_service_info_.instance_id); + app_->request_service(vsomeip::service_t(remote_service_info_.service_id + 1), vsomeip::instance_t(remote_service_info_.instance_id + 1)); + app_->request_service(vsomeip::service_t(remote_service_info_.service_id + 2), vsomeip::instance_t(remote_service_info_.instance_id + 2)); + + app_->start(); + } + + ~offered_services_info_test_client() { + test_offered_services_thread_.join(); + stop_thread_.join(); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + VSOMEIP_INFO << "Service [" << std::setw(4) + << std::setfill('0') << std::hex << _service << "." << _instance + << "] is " << (_is_available ? "available":"not available") << "."; + static int services_available =0; + std::lock_guard its_lock(mutex_); + if(_is_available) { + services_available++; + if (services_available == 5) { + wait_until_service_available_ = false; + condition_.notify_one(); + } + } else { + wait_until_service_available_ = true; + condition_.notify_one(); + } + } + + void on_message(const std::shared_ptr &_message) { + if (_message->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + on_response(_message); + } + } + + void on_response(const std::shared_ptr &_message) { + ++number_received_responses_; + static bool first(true); + if (first) { + first = false; + last_received_response_ = std::chrono::steady_clock::now(); + return; + } + EXPECT_EQ(service_info_.service_id, _message->get_service()); + EXPECT_EQ(service_info_.method_id, _message->get_method()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + ASSERT_LT(std::chrono::duration_cast( + std::chrono::steady_clock::now() - last_received_response_).count(), + (std::chrono::milliseconds(VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT) + + std::chrono::milliseconds(1000)).count()); + last_received_response_ = std::chrono::steady_clock::now(); + std::cout << "."; + std::cout.flush(); + } + + void test_offered_services() { + if (operation_mode_ != operation_mode_e::METHODCALL) { + return; + } + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + while (wait_until_service_available_) { + condition_.wait(its_lock); + } + its_lock.unlock(); + its_lock.release(); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + VSOMEIP_INFO << "TEST LOCAL SERVICES"; + app_->get_offered_services_async(vsomeip::offer_type_e::OT_LOCAL, std::bind(&offered_services_info_test_client::on_offered_services_local, this, std::placeholders::_1)); + + // send shutdown command to service + if (std::future_status::timeout == all_callbacks_received_.get_future().wait_for(std::chrono::seconds(15))) { + ADD_FAILURE() << "Didn't receive all callbacks within time"; + } else { + std::shared_ptr its_req = vsomeip::runtime::get()->create_request(); + its_req->set_service(service_info_.service_id); + its_req->set_instance(service_info_.instance_id); + its_req->set_method(service_info_.shutdown_method_id); + app_->send(its_req); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + { + std::lock_guard its_lock(stop_mutex_); + wait_for_stop_ = false; + VSOMEIP_INFO << "going down. Sent shutdown command to service"; + stop_condition_.notify_one(); + } + } + + void on_offered_services_local( const std::vector> &_services) { + std::cout << "ON OFFERED SERVICES LOCAL CALLBACK START" << std::endl; + EXPECT_EQ(2u, _services.size()); + bool local_service_test_failed(true); + for (auto its_pair : _services) { + local_service_test_failed = true; + std::cout << "CALLBACK VALUE -> Service: "<< std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; + auto found_service = local_offered_services.find(its_pair.first); + if (found_service != local_offered_services.end()) { + auto found_instance = found_service->second.find(its_pair.second); + if (found_instance != found_service->second.end()) { + local_service_test_failed = false; + } + } + EXPECT_FALSE(local_service_test_failed); + } + std::cout << "ON OFFERED SERVICES LOCAL CALLBACK END" << std::endl; + VSOMEIP_INFO << "TEST REMOTE SERVICES"; + app_->get_offered_services_async(vsomeip::offer_type_e::OT_REMOTE, std::bind(&offered_services_info_test_client::on_offered_services_remote, this, std::placeholders::_1)); + } + + void on_offered_services_remote( const std::vector> &_services) { + std::cout << "ON OFFERED SERVICES REMOTE CALLBACK START" << std::endl; + EXPECT_EQ(3u, _services.size()); + bool remote_service_test_failed(true); + for (auto its_pair : _services) { + remote_service_test_failed = true; + std::cout << "CALLBACK VALUE -> Service: " << std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; + auto found_service = remote_offered_services.find(its_pair.first); + if (found_service != remote_offered_services.end()) { + auto found_instance = found_service->second.find(its_pair.second); + if (found_instance != found_service->second.end()) { + remote_service_test_failed = false; + } + } + EXPECT_FALSE(remote_service_test_failed); + } + std::cout << "ON OFFERED SERVICES REMOTE CALLBACK END" << std::endl; + VSOMEIP_INFO << "TEST ALL SERVICES"; + app_->get_offered_services_async(vsomeip::offer_type_e::OT_ALL, std::bind(&offered_services_info_test_client::on_offered_services_all, this, std::placeholders::_1)); + } + + void on_offered_services_all( const std::vector> &_services) { + std::cout << "ON OFFERED SERVICES ALL CALLBACK START" << std::endl; + EXPECT_EQ(5u, _services.size()); + bool all_service_test_failed(true); + for (auto its_pair : _services) { + all_service_test_failed = true; + std::cout << "CALLBACK VALUE -> Service: " << std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; + auto found_service = all_offered_services.find(its_pair.first); + if (found_service != all_offered_services.end()) { + auto found_instance = found_service->second.find(its_pair.second); + if (found_instance != found_service->second.end()) { + all_service_test_failed = false; + } + } + EXPECT_FALSE(all_service_test_failed); + } + std::cout << "ON OFFERED SERVICES ALL CALLBACK END" << std::endl; + all_callbacks_received_.set_value(); + } + + void wait_for_stop() { + std::unique_lock its_lock(stop_mutex_); + while (wait_for_stop_) { + stop_condition_.wait(its_lock); + } + VSOMEIP_INFO << "going down"; + app_->clear_all_handler(); + app_->stop(); + } + +private: + struct offer_test::service_info service_info_; + struct offer_test::service_info remote_service_info_; + operation_mode_e operation_mode_; + std::shared_ptr app_; + + bool wait_until_registered_; + bool wait_until_service_available_; + std::mutex mutex_; + std::condition_variable condition_; + + bool wait_for_stop_; + std::mutex stop_mutex_; + std::condition_variable stop_condition_; + + std::chrono::steady_clock::time_point last_received_response_; + std::atomic number_received_responses_; + std::promise all_callbacks_received_; + std::thread stop_thread_; + std::thread test_offered_services_thread_; +}; + +static operation_mode_e passed_mode = operation_mode_e::METHODCALL; + +TEST(someip_offered_services_info_test, check_offered_services) +{ + offered_services_info_test_client its_sample(offer_test::service, offer_test::remote_service, passed_mode); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a operation mode, like: " << argv[0] << " SUBSCRIBE" << std::endl; + std::cerr << "Valid operation modes are SUBSCRIBE and METHODCALL" << std::endl; + return 1; + } + + if (std::string("SUBSCRIBE") == std::string(argv[1])) { + passed_mode = operation_mode_e::SUBSCRIBE; + } else if (std::string("METHODCALL") == std::string(argv[1])) { + passed_mode = operation_mode_e::METHODCALL; + } else { + std::cerr << "Wrong operation mode passed, exiting" << std::endl; + std::cerr << "Please specify a operation mode, like: " << argv[0] << " SUBSCRIBE" << std::endl; + std::cerr << "Valid operation modes are SUBSCRIBE and METHODCALL" << std::endl; + return 1; + } + +#if 0 + if (argc >= 4 && std::string("SAME_SERVICE_ID") == std::string(argv[3])) { + use_same_service_id = true; + } else { + use_same_service_id = false; + } +#endif + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/offered_services_info_test/offered_services_info_test_globals.hpp b/test/network_tests/offered_services_info_test/offered_services_info_test_globals.hpp new file mode 100644 index 0000000..b74dfab --- /dev/null +++ b/test/network_tests/offered_services_info_test/offered_services_info_test_globals.hpp @@ -0,0 +1,29 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef OFFER_TEST_GLOBALS_HPP_ +#define OFFER_TEST_GLOBALS_HPP_ + +namespace offer_test { + +struct service_info { + vsomeip::service_t service_id; + vsomeip::instance_t instance_id; + vsomeip::method_t method_id; + vsomeip::event_t event_id; + vsomeip::eventgroup_t eventgroup_id; + vsomeip::method_t shutdown_method_id; +}; + +uint8_t num_all_offered_services = 5; +uint8_t num_local_offered_services = 2; +uint8_t num_remote_offered_services = 3; + + +struct service_info service = { 0x1111, 0x1, 0x1111, 0x1111, 0x1000, 0x1404 }; +struct service_info remote_service = { 0x2222, 0x2, 0x2222, 0x2222, 0x2000, 0x2808 }; +} + +#endif /* OFFER_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/offered_services_info_test/offered_services_info_test_local.json b/test/network_tests/offered_services_info_test/offered_services_info_test_local.json new file mode 100644 index 0000000..872ebd2 --- /dev/null +++ b/test/network_tests/offered_services_info_test/offered_services_info_test_local.json @@ -0,0 +1,57 @@ +{ + "unicast" : "127.0.0.1", + "diagnosis":"0x12", + "logging" : + { + "level" : "warning", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/tmp/vsomeip.log" + }, + + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "offered_services_info_test_service", + "id" : "0x1277" + } + ], + + "services" : + [ + { + "service" : "0x1111", + "instance" : "0x1" + }, + { + "service" : "0x2222", + "instance" : "0x2", + "reliable" : { "port" : "30502" }, + "unreliable" : "31002" + }, + { + "service" : "0x2223", + "instance" : "0x3", + "reliable" : { "port" : "30503" } + }, + { + "service" : "0x2224", + "instance" : "0x4", + "unreliable" : "31004" + } + ], + + "routing" : "routingmanagerd", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp" + } +} diff --git a/test/network_tests/offered_services_info_test/offered_services_info_test_local_starter.sh b/test/network_tests/offered_services_info_test/offered_services_info_test_local_starter.sh new file mode 100755 index 0000000..50047db --- /dev/null +++ b/test/network_tests/offered_services_info_test/offered_services_info_test_local_starter.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +FAIL=0 + +cat < should be +# rejected and an error message should be printed. +# * Message exchange with client application should not be interrupted. + +# Array for client pids +CLIENT_PIDS=() +export VSOMEIP_CONFIGURATION=offered_services_info_test_local.json +# Start the services (routingmanagerd as app name) +./offered_services_info_test_service 1 & #routingmanagerd as app name +PID_SERVICE_ONE=$! +./offered_services_info_test_client METHODCALL & +CLIENT_PIDS+=($!) + +# Wait until all clients are finished +for job in ${CLIENT_PIDS[*]} +do + # Fail gets incremented if a client exits with a non-zero exit code + wait $job || FAIL=$(($FAIL+1)) +done + +# kill the services +kill $PID_SERVICE_ONE +sleep 1 + + +# Check if everything went well +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/offered_services_info_test/offered_services_info_test_service.cpp b/test/network_tests/offered_services_info_test/offered_services_info_test_service.cpp new file mode 100644 index 0000000..3e0465c --- /dev/null +++ b/test/network_tests/offered_services_info_test/offered_services_info_test_service.cpp @@ -0,0 +1,264 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#ifdef ANDROID +#include "../../implementation/configuration/include/internal_android.hpp" +#else +#include "../../implementation/configuration/include/internal.hpp" +#endif // ANDROID + +#include "offered_services_info_test_globals.hpp" + +static std::string service_number; +std::map> all_offered_services; +std::map> local_offered_services; +std::map> remote_offered_services; + + +class offer_test_service { +public: + offer_test_service(struct offer_test::service_info _service_info, struct offer_test::service_info _remote_service_info) : + service_info_(_service_info), + remote_service_info_(_remote_service_info), + // service with number 1 uses "routingmanagerd" as application name + // this way the same json file can be reused for all local tests + // including the ones with routingmanagerd + app_(vsomeip::runtime::get()->create_application( + (service_number == "1") ? "routingmanagerd" : + "offered_services_info_test_service" + service_number)), + wait_until_registered_(true), + shutdown_method_called_(false), + offer_thread_(std::bind(&offer_test_service::run, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&offer_test_service::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.method_id, + std::bind(&offer_test_service::on_request, this, + std::placeholders::_1)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.shutdown_method_id, + std::bind(&offer_test_service::on_shutdown_method_called, this, + std::placeholders::_1)); + app_->start(); + } + + ~offer_test_service() { + offer_thread_.join(); + } + + void offer() { + //offer local services + app_->offer_service(service_info_.service_id, service_info_.instance_id); + local_offered_services[service_info_.service_id].insert(service_info_.instance_id); + all_offered_services[service_info_.service_id].insert(service_info_.instance_id); + + app_->offer_service(service_info_.service_id, (vsomeip::instance_t)(service_info_.instance_id + 1)); + local_offered_services[service_info_.service_id].insert((vsomeip::instance_t)(service_info_.instance_id + 1)); + all_offered_services[service_info_.service_id].insert((vsomeip::instance_t)(service_info_.instance_id + 1)); + + // offer remote service ID 0x2222 instance ID 0x2 (port configuration added to json file) + app_->offer_service(remote_service_info_.service_id, remote_service_info_.instance_id); // reliable and unreliable port + remote_offered_services[remote_service_info_.service_id].insert(remote_service_info_.instance_id); + all_offered_services[remote_service_info_.service_id].insert(remote_service_info_.instance_id); + + + app_->offer_service((vsomeip::service_t)(remote_service_info_.service_id + 1), (vsomeip::instance_t)(remote_service_info_.instance_id + 1)); // only reliable port + remote_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 1)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 1)); + all_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 1)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 1)); + + + app_->offer_service((vsomeip::service_t)(remote_service_info_.service_id + 2), (vsomeip::instance_t)(remote_service_info_.instance_id + 2)); // only unreliable port + remote_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 2)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 2)); + all_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 2)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 2)); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_request(const std::shared_ptr &_message) { + app_->send(vsomeip::runtime::get()->create_response(_message)); + } + + void on_shutdown_method_called(const std::shared_ptr &_message) { + (void)_message; + shutdown_method_called_ = true; + + app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); + app_->stop_offer_service(service_info_.service_id, (vsomeip::instance_t)(service_info_.instance_id + 1)); + + app_->stop_offer_service(remote_service_info_.service_id, remote_service_info_.instance_id); // reliable and unreliable port + app_->stop_offer_service((vsomeip::service_t)(remote_service_info_.service_id + 1), (vsomeip::instance_t)(remote_service_info_.instance_id + 1)); // only reliable port + app_->stop_offer_service((vsomeip::service_t)(remote_service_info_.service_id + 2), (vsomeip::instance_t)(remote_service_info_.instance_id + 2)); // only unreliable port + + app_->clear_all_handler(); + app_->stop(); + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + VSOMEIP_INFO << "TEST LOCAL SERVICES"; + app_->get_offered_services_async(vsomeip::offer_type_e::OT_LOCAL, std::bind(&offer_test_service::on_offered_services_local, this, std::placeholders::_1)); + + if (std::future_status::timeout == all_callbacks_received_.get_future().wait_for(std::chrono::seconds(15))) { + ADD_FAILURE() << "Didn't receive all callbacks within time"; + } + + while(!shutdown_method_called_) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + } + + + void on_offered_services_local( const std::vector> &_services) { + std::cout << "ON OFFERED SERVICES LOCAL CALLBACK START" << std::endl; + EXPECT_EQ(2u, _services.size()); + bool local_service_test_failed(true); + uint16_t i=0; + for (auto its_pair : _services) { + local_service_test_failed = true; + std::cout << "CALLBACK VALUE -> Service: "<< std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; + auto found_service = local_offered_services.find(its_pair.first); + if (found_service != local_offered_services.end()) { + auto found_instance = found_service->second.find(its_pair.second); + if (found_instance != found_service->second.end()) { + i++; + local_service_test_failed = false; + } + } + EXPECT_FALSE(local_service_test_failed); + } + EXPECT_EQ(offer_test::num_local_offered_services, i); + + std::cout << "ON OFFERED SERVICES LOCAL CALLBACK END" << std::endl; + + VSOMEIP_INFO << "TEST REMOTE SERVICES"; + app_->get_offered_services_async(vsomeip::offer_type_e::OT_REMOTE, std::bind(&offer_test_service::on_offered_services_remote, this, std::placeholders::_1)); + } + + + void on_offered_services_remote( const std::vector> &_services) { + std::cout << "ON OFFERED SERVICES REMOTE CALLBACK START" << std::endl; + EXPECT_EQ(3u, _services.size()); + bool remote_service_test_failed(true); + uint16_t i=0; + for (auto its_pair : _services) { + remote_service_test_failed = true; + std::cout << "CALLBACK VALUE -> Service: " << std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; + auto found_service = remote_offered_services.find(its_pair.first); + if (found_service != remote_offered_services.end()) { + auto found_instance = found_service->second.find(its_pair.second); + if (found_instance != found_service->second.end()) { + i++; + remote_service_test_failed = false; + } + } + EXPECT_FALSE(remote_service_test_failed); + } + EXPECT_EQ(offer_test::num_remote_offered_services, i); + + std::cout << "ON OFFERED SERVICES REMOTE CALLBACK END" << std::endl; + + VSOMEIP_INFO << "TEST ALL SERVICES"; + app_->get_offered_services_async(vsomeip::offer_type_e::OT_ALL, std::bind(&offer_test_service::on_offered_services_all, this, std::placeholders::_1)); + } + + + void on_offered_services_all( const std::vector> &_services) { + std::cout << "ON OFFERED SERVICES ALL CALLBACK START" << std::endl; + EXPECT_EQ(5u, _services.size()); + bool all_service_test_failed(true); + uint16_t i=0; + for (auto its_pair : _services) { + all_service_test_failed = true; + std::cout << "CALLBACK VALUE -> Service: " << std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; + auto found_service = all_offered_services.find(its_pair.first); + if (found_service != all_offered_services.end()) { + auto found_instance = found_service->second.find(its_pair.second); + if (found_instance != found_service->second.end()) { + i++; + all_service_test_failed = false; + } + } + EXPECT_FALSE(all_service_test_failed); + } + EXPECT_EQ(offer_test::num_all_offered_services, i); + std::cout << "ON OFFERED SERVICES ALL CALLBACK END" << std::endl; + all_callbacks_received_.set_value(); + } + +private: + struct offer_test::service_info service_info_; + struct offer_test::service_info remote_service_info_; + std::shared_ptr app_; + + bool wait_until_registered_; + std::mutex mutex_; + std::condition_variable condition_; + std::atomic shutdown_method_called_; + std::promise all_callbacks_received_; + std::thread offer_thread_; +}; + +TEST(someip_offered_services_info_test, check_offered_services_as_rm_impl) +{ + offer_test_service its_sample(offer_test::service, offer_test::remote_service); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a service number, like: " << argv[0] << " 2" << std::endl; + return 1; + } + + service_number = std::string(argv[1]); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/payload_tests/conf/external_local_payload_test_client_external.json.in b/test/network_tests/payload_tests/conf/external_local_payload_test_client_external.json.in new file mode 100644 index 0000000..0abaea2 --- /dev/null +++ b/test/network_tests/payload_tests/conf/external_local_payload_test_client_external.json.in @@ -0,0 +1,53 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "true", + "path" : "/var/log/vsomeip.log" + }, + + "dlt" : "true" + }, + + "applications" : + [ + { + "name" : "external_local_payload_test_client_external", + "id" : "0x1343" + } + ], + + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509", + "reliable" : + { + "port" : "30510", + "enable-magic-cookies" : "false" + } + } + ], + "npdu-default-timings" : { + "debounce-time-request" : "0", + "debounce-time-response" : "0", + "max-retention-time-request" : "0", + "max-retention-time-response" : "0" + }, + "routing" : "external_local_payload_test_client_external", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30491", + "protocol" : "udp" + } +} diff --git a/test/network_tests/payload_tests/conf/external_local_payload_test_client_local.json.in b/test/network_tests/payload_tests/conf/external_local_payload_test_client_local.json.in new file mode 100644 index 0000000..1f4fd6d --- /dev/null +++ b/test/network_tests/payload_tests/conf/external_local_payload_test_client_local.json.in @@ -0,0 +1,54 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "true", + "path" : "/var/log/vsomeip.log" + }, + + "dlt" : "true" + }, + + "applications" : + [ + { + "name" : "external_local_payload_test_client_local", + "id" : "0x1343" + } + ], + + + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509", + "reliable" : + { + "port" : "30510", + "enable-magic-cookies" : "false" + } + } + ], + "npdu-default-timings" : { + "debounce-time-request" : "0", + "debounce-time-response" : "0", + "max-retention-time-request" : "0", + "max-retention-time-response" : "0" + }, + "routing" : "external_local_payload_test_service", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30491", + "protocol" : "udp" + } +} diff --git a/test/network_tests/payload_tests/conf/external_local_payload_test_service.json.in b/test/network_tests/payload_tests/conf/external_local_payload_test_service.json.in new file mode 100644 index 0000000..aaeae82 --- /dev/null +++ b/test/network_tests/payload_tests/conf/external_local_payload_test_service.json.in @@ -0,0 +1,51 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/tmp/vsomeip.log" + }, + + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "external_local_payload_test_service", + "id" : "0x1277" + } + ], + + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unreliable" : "30509", + "reliable" : + { + "port" : "30510", + "enable-magic-cookies" : "false" + } + } + ], + "npdu-default-timings" : { + "debounce-time-request" : "0", + "debounce-time-response" : "0", + "max-retention-time-request" : "0", + "max-retention-time-response" : "0" + }, + "routing" : "external_local_payload_test_service", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp" + } +} diff --git a/test/network_tests/payload_tests/external_local_payload_test_client_external_start.sh b/test/network_tests/payload_tests/external_local_payload_test_client_external_start.sh new file mode 100755 index 0000000..5f6b7ea --- /dev/null +++ b/test/network_tests/payload_tests/external_local_payload_test_client_external_start.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_external +export VSOMEIP_CONFIGURATION=external_local_payload_test_client_external.json +./payload_test_client --udp --max-payload-size UDP +# We sleep to let the service restart with --tcp option so we can test +# communication via TCP. +sleep 5 +./payload_test_client --tcp --max-payload-size TCP diff --git a/test/network_tests/payload_tests/external_local_payload_test_client_external_starter.sh b/test/network_tests/payload_tests/external_local_payload_test_client_external_starter.sh new file mode 100755 index 0000000..af044cf --- /dev/null +++ b/test/network_tests/payload_tests/external_local_payload_test_client_external_starter.sh @@ -0,0 +1,121 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit sucessfully. + +FAIL=0 + +# Parameter 1: the pid to check +# Parameter 2: number of TCP/UDP sockets the process should have open +check_tcp_udp_sockets_are_open () +{ + # Check that the passed pid/process does listen on at least one TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -lt $2 ] + then + ((FAIL+=1)) + fi +} + +# Parameter 1: the pid to check +check_tcp_udp_sockets_are_closed () +{ + # Check that the passed pid/process does not listen on any TCP/UDP socket + # or has any active connection via a TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] + then + ((FAIL+=1)) + fi + + SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] + then + ((FAIL+=1)) + fi +} + +# Start the service for payload test with UDP +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service +export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json +./payload_test_service --udp & +SERIVCE_PID=$! + +# Display a message to show the user that he must now call the external client +# to finish the test successfully +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting external local payload on slave LXC" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./external_local_payload_test_client_external_start.sh\"" & + echo "remote ssh job id: $!" +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_payload_test_client_external_start.sh" & +else +cat < /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -lt $2 ] + then + ((FAIL+=1)) + fi +} + +# Parameter 1: the pid to check +check_tcp_udp_sockets_are_closed () +{ + # Check that the passed pid/process does not listen on any TCP/UDP socket + # or has any active connection via a TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] + then + ((FAIL+=1)) + fi + + SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] + then + ((FAIL+=1)) + fi +} + +# Start the service +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service +export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json +./payload_test_service & +SERIVCE_PID=$! +sleep 1; + +# The service should listen on a TCP and UDP socket now +check_tcp_udp_sockets_are_open $SERIVCE_PID 2 + +# Start the client which sends messages over local UDS +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_local +export VSOMEIP_CONFIGURATION=external_local_payload_test_client_local.json +./payload_test_client --dont-shutdown-service & +CLIENT_PID=$! +sleep 1 + +check_tcp_udp_sockets_are_open $SERIVCE_PID 2 +check_tcp_udp_sockets_are_closed $CLIENT_PID + +# Wait until client is finished +wait $CLIENT_PID || ((FAIL+=1)) + +# Display a message to show the user that he must now call the external client +# to finish the test successfully +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting external local payload on slave LXC" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./external_local_payload_test_client_external_start.sh\"" & + echo "remote ssh job id: $!" +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_payload_test_client_external_start.sh" & +else +cat < /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -lt $2 ] + then + ((FAIL+=1)) + fi +} + +# Parameter 1: the pid to check +check_tcp_udp_sockets_are_closed () +{ + # Check that the passed pid/process does not listen on any TCP/UDP socket + # or has any active connection via a TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] + then + ((FAIL+=1)) + fi + + SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] + then + ((FAIL+=1)) + fi +} + +# Start the service +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service +export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json +./payload_test_service & +SERIVCE_PID=$! +sleep 1; + +# The service should listen on a TCP and UDP socket now +check_tcp_udp_sockets_are_open $SERIVCE_PID 2 + +# Start the client +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_local +export VSOMEIP_CONFIGURATION=external_local_payload_test_client_local.json +./payload_test_client & +CLIENT_PID=$! + +# The service should still listen on a TCP and UDP socket now +check_tcp_udp_sockets_are_open $SERIVCE_PID 2 +# The client should use the shortcut over a local UDS instead of TCP/UDP, +# therefore he shouldn't have any open TCP/UDP sockets +check_tcp_udp_sockets_are_closed $CLIENT_PID + +if [ ! -z "$USE_DOCKER" ]; then + FAIL=0 +fi + +# Wait until client and service are finished +for job in $(jobs -p) +do + # Fail gets incremented if either client or service exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +# Check if client and server both exited sucessfully +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/payload_tests/external_local_payload_test_service_client_external_start.sh b/test/network_tests/payload_tests/external_local_payload_test_service_client_external_start.sh new file mode 100755 index 0000000..046d50b --- /dev/null +++ b/test/network_tests/payload_tests/external_local_payload_test_service_client_external_start.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service +export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json +./payload_test_service --udp +# After payload was measured with UDP the client will restart and measure +# throughput with TCP +./payload_test_service --tcp \ No newline at end of file diff --git a/test/network_tests/payload_tests/external_local_payload_test_service_start.sh b/test/network_tests/payload_tests/external_local_payload_test_service_start.sh new file mode 100755 index 0000000..90b1b38 --- /dev/null +++ b/test/network_tests/payload_tests/external_local_payload_test_service_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service +export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json +./payload_test_service diff --git a/test/network_tests/payload_tests/local_payload_test_client.json b/test/network_tests/payload_tests/local_payload_test_client.json new file mode 100644 index 0000000..24fa1fa --- /dev/null +++ b/test/network_tests/payload_tests/local_payload_test_client.json @@ -0,0 +1,36 @@ +{ + "unicast" : "127.0.0.1", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "true", + "path" : "/var/log/vsomeip.log" + }, + + "dlt" : "true" + }, + + "applications" : + [ + { + "name" : "local_payload_test_client", + "id" : "0x1343" + } + ], + "services" : + [ + ], + + "routing" : "local_payload_test_service", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30491", + "protocol" : "udp" + } +} diff --git a/test/network_tests/payload_tests/local_payload_test_client_start.sh b/test/network_tests/payload_tests/local_payload_test_client_start.sh new file mode 100755 index 0000000..975be2a --- /dev/null +++ b/test/network_tests/payload_tests/local_payload_test_client_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=local_payload_test_client +export VSOMEIP_CONFIGURATION=local_payload_test_client.json +./payload_test_client diff --git a/test/network_tests/payload_tests/local_payload_test_huge_payload_starter.sh b/test/network_tests/payload_tests/local_payload_test_huge_payload_starter.sh new file mode 100755 index 0000000..c230891 --- /dev/null +++ b/test/network_tests/payload_tests/local_payload_test_huge_payload_starter.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit sucessfully. + +FAIL=0 + +# Start the service +export VSOMEIP_APPLICATION_NAME=local_payload_test_service +export VSOMEIP_CONFIGURATION=local_payload_test_service.json +./payload_test_service & +SERIVCE_PID=$! +sleep 1; + +# Start the client +export VSOMEIP_APPLICATION_NAME=local_payload_test_client +export VSOMEIP_CONFIGURATION=local_payload_test_client.json +./payload_test_client --number-of-messages 100 --max-payload-size 10485760 & +CLIENT_PID=$! + +# Wait until client and service are finished +for job in $(jobs -p) +do + # Fail gets incremented if either client or service exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +# Check if client and server both exited sucessfully and the service didnt't +# have any open tcp/udp sockets +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/payload_tests/local_payload_test_service.json b/test/network_tests/payload_tests/local_payload_test_service.json new file mode 100644 index 0000000..b5c83a6 --- /dev/null +++ b/test/network_tests/payload_tests/local_payload_test_service.json @@ -0,0 +1,40 @@ +{ + "unicast" : "127.0.0.1", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/tmp/vsomeip.log" + }, + + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "local_payload_test_service", + "id" : "0x1277" + } + ], + + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678" + } + ], + + "routing" : "local_payload_test_service", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp" + } +} diff --git a/test/network_tests/payload_tests/local_payload_test_service_start.sh b/test/network_tests/payload_tests/local_payload_test_service_start.sh new file mode 100755 index 0000000..cc67f54 --- /dev/null +++ b/test/network_tests/payload_tests/local_payload_test_service_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=local_payload_test_service +export VSOMEIP_CONFIGURATION=local_payload_test_service.json +./payload_test_service diff --git a/test/network_tests/payload_tests/local_payload_test_starter.sh b/test/network_tests/payload_tests/local_payload_test_starter.sh new file mode 100755 index 0000000..abc4577 --- /dev/null +++ b/test/network_tests/payload_tests/local_payload_test_starter.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit sucessfully. + +FAIL=0 + +# Parameter 1: the pid to check +check_tcp_udp_sockets_are_closed () +{ + # Check that the service does not listen on any TCP/UDP socket + # or has any active connection via a TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] + then + ((FAIL+=1)) + fi + + SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] + then + ((FAIL+=1)) + fi +} + +# Start the service +export VSOMEIP_APPLICATION_NAME=local_payload_test_service +export VSOMEIP_CONFIGURATION=local_payload_test_service.json +./payload_test_service & +SERIVCE_PID=$! +sleep 1; + +check_tcp_udp_sockets_are_closed $SERIVCE_PID + +# Start the client +export VSOMEIP_APPLICATION_NAME=local_payload_test_client +export VSOMEIP_CONFIGURATION=local_payload_test_client.json +./payload_test_client & +CLIENT_PID=$! + +check_tcp_udp_sockets_are_closed $SERIVCE_PID +check_tcp_udp_sockets_are_closed $CLIENT_PID + +# Wait until client and service are finished +for job in $(jobs -p) +do + # Fail gets incremented if either client or service exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +# Check if client and server both exited sucessfully and the service didnt't +# have any open tcp/udp sockets +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/payload_tests/payload_test_client.cpp b/test/network_tests/payload_tests/payload_test_client.cpp new file mode 100644 index 0000000..fd235d8 --- /dev/null +++ b/test/network_tests/payload_tests/payload_test_client.cpp @@ -0,0 +1,415 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "payload_test_client.hpp" + +enum class payloadsize + : std::uint8_t + { + UDS, TCP, UDP, USER_SPECIFIED +}; + +// this variables are changed via cmdline parameters +static bool use_tcp = false; +static bool call_service_sync = true; +static std::uint32_t sliding_window_size = vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS; +static payloadsize max_payload_size = payloadsize::UDS; +static bool shutdown_service_at_end = true; +static std::uint32_t user_defined_max_payload; +static std::uint32_t number_of_messages_to_send = 0; + +payload_test_client::payload_test_client( + bool _use_tcp, + bool _call_service_sync, + std::uint32_t _sliding_window_size) : + app_(vsomeip::runtime::get()->create_application()), + request_(vsomeip::runtime::get()->create_request(_use_tcp)), + call_service_sync_(_call_service_sync), + sliding_window_size_(_sliding_window_size), + blocked_(false), + is_available_(false), + number_of_messages_to_send_(number_of_messages_to_send ? number_of_messages_to_send : vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS), + number_of_sent_messages_(0), + number_of_sent_messages_total_(0), + number_of_acknowledged_messages_(0), + current_payload_size_(1), + all_msg_acknowledged_(false), + sender_(std::bind(&payload_test_client::run, this)) +{ +} + +bool payload_test_client::init() +{ + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + + app_->register_state_handler( + std::bind(&payload_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, + std::bind(&payload_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&payload_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + return true; +} + +void payload_test_client::start() +{ + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void payload_test_client::stop() +{ + VSOMEIP_INFO << "Stopping..."; + // shutdown the service + if(shutdown_service_at_end) + { + shutdown_service(); + } + app_->clear_all_handler(); +} + +void payload_test_client::shutdown_service() +{ + request_->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request_->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + request_->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); + app_->send(request_); +} + +void payload_test_client::join_sender_thread() +{ + sender_.join(); +} + +void payload_test_client::on_state(vsomeip::state_type_e _state) +{ + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); + } +} + +void payload_test_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) +{ + VSOMEIP_INFO << "Service [" << std::setw(4) << std::setfill('0') << std::hex + << _service << "." << _instance << "] is " + << (_is_available ? "available." : "NOT available."); + + if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service + && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) + { + if(is_available_ && !_is_available) + { + is_available_ = false; + } + else if(_is_available && !is_available_) + { + is_available_ = true; + send(); + } + } +} + +void payload_test_client::on_message(const std::shared_ptr& _response) +{ + number_of_acknowledged_messages_++; + + ASSERT_EQ(_response->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID); + ASSERT_EQ(_response->get_instance(), vsomeip_test::TEST_SERVICE_INSTANCE_ID); + + if(call_service_sync_) + { + // We notify the sender thread every time a message was acknowledged + { + std::lock_guard lk(all_msg_acknowledged_mutex_); + all_msg_acknowledged_ = true; + } + all_msg_acknowledged_cv_.notify_one(); + } + else + { + // We notify the sender thread only if all sent messages have been acknowledged + if(number_of_acknowledged_messages_ == number_of_messages_to_send_) + { + std::lock_guard lk(all_msg_acknowledged_mutex_); + number_of_acknowledged_messages_ = 0; + all_msg_acknowledged_ = true; + all_msg_acknowledged_cv_.notify_one(); + } + else if(number_of_acknowledged_messages_ % sliding_window_size_ == 0) + { + std::lock_guard lk(all_msg_acknowledged_mutex_); + all_msg_acknowledged_ = true; + all_msg_acknowledged_cv_.notify_one(); + } + } +} + +void payload_test_client::send() +{ + std::lock_guard its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); +} + +void payload_test_client::run() +{ + std::unique_lock its_lock(mutex_); + while (!blocked_) + { + condition_.wait(its_lock); + } + + request_->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request_->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + request_->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); + + // lock the mutex + std::unique_lock lk(all_msg_acknowledged_mutex_); + + std::uint32_t max_allowed_payload = get_max_allowed_payload(); + + std::shared_ptr payload = vsomeip::runtime::get()->create_payload(); + std::vector payload_data; + bool reached_peak = false; + for(;;) + { + payload_data.assign(current_payload_size_ , vsomeip_test::PAYLOAD_TEST_DATA); + payload->set_data(payload_data); + request_->set_payload(payload); + + watch_.reset(); + watch_.start(); + + call_service_sync_ ? send_messages_sync(lk) : send_messages_async(lk); + + watch_.stop(); + print_throughput(); + + // Increase array size for next iteration + if(!reached_peak) { + current_payload_size_ *= 2; + } else { + current_payload_size_ /= 2; + } + + if(!reached_peak && current_payload_size_ > max_allowed_payload) + { + current_payload_size_ = max_allowed_payload; + reached_peak = true; + } else if(reached_peak && current_payload_size_ <= 1) { + break; + } + } + blocked_ = false; + + stop(); + std::thread t1([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 5));}); + t1.join(); + app_->stop(); + std::thread t([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 5));}); + t.join(); +} + + +std::uint32_t payload_test_client::get_max_allowed_payload() +{ + std::uint32_t payload; + switch (max_payload_size) + { + case payloadsize::UDS: + // TODO + payload = 1024 * 32 - 16; + break; + case payloadsize::TCP: + // TODO + payload = 4095 - 16; + break; + case payloadsize::UDP: + payload = VSOMEIP_MAX_UDP_MESSAGE_SIZE - 16; + break; + case payloadsize::USER_SPECIFIED: + payload = user_defined_max_payload; + break; + default: + payload = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE; + break; + } + return payload; +} + +void payload_test_client::send_messages_sync(std::unique_lock& lk) +{ + for (number_of_sent_messages_ = 0; + number_of_sent_messages_ < number_of_messages_to_send_; + number_of_sent_messages_++, number_of_sent_messages_total_++) + { + app_->send(request_); + // wait until the send messages has been acknowledged + // as long we wait lk is released; after wait returns lk is reacquired + all_msg_acknowledged_cv_.wait(lk, [&] + { return all_msg_acknowledged_;}); + // Reset condition variable (lk is locked again here) + all_msg_acknowledged_ = false; + } +} + +void payload_test_client::send_messages_async(std::unique_lock& lk) +{ + for (number_of_sent_messages_ = 0; + number_of_sent_messages_ < number_of_messages_to_send_; + number_of_sent_messages_++, number_of_sent_messages_total_++) + { + app_->send(request_); + + if((number_of_sent_messages_+1) % sliding_window_size_ == 0) + { + // wait until all send messages have been acknowledged + // as long we wait lk is released; after wait returns lk is reacquired + all_msg_acknowledged_cv_.wait(lk, [&] + { return all_msg_acknowledged_;}); + + // Reset condition variable + all_msg_acknowledged_ = false; + } + } +} + +void payload_test_client::print_throughput() +{ + constexpr std::uint32_t usec_per_sec = 1000000; + stop_watch::usec_t time_needed = watch_.get_total_elapsed_microseconds(); + stop_watch::usec_t time_per_message = time_needed / number_of_sent_messages_; + std::double_t calls_per_sec = number_of_sent_messages_ + * (usec_per_sec / static_cast(time_needed)); + std::double_t mbyte_per_sec = ((number_of_sent_messages_ + * current_payload_size_) + / (static_cast(time_needed) / usec_per_sec)) / (1024*1024); + + VSOMEIP_INFO<< "[ Payload Test ] : :" + << "Payload size [byte]: " << std::dec << std::setw(8) << std::setfill('0') << current_payload_size_ + << " Messages sent: " << std::dec << std::setw(8) << std::setfill('0') << number_of_sent_messages_ + << " Meantime/message [usec]: " << std::dec << std::setw(8) << std::setfill('0') << time_per_message + << " Calls/sec: " << std::dec << std::setw(8) << std::setfill('0') << calls_per_sec + << " MiB/sec: " << std::dec << std::setw(8) << std::setfill('0') << mbyte_per_sec; +} + +TEST(someip_payload_test, send_different_payloads) +{ + payload_test_client test_client_(use_tcp, call_service_sync, sliding_window_size); + if (test_client_.init()) { + test_client_.start(); + test_client_.join_sender_thread(); + } +} + + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + std::string tcp_enable("--tcp"); + std::string udp_enable("--udp"); + std::string sync_enable("--sync"); + std::string async_enable("--async"); + std::string sliding_window_size_param("--sliding-window-size"); + std::string max_payload_size_param("--max-payload-size"); + std::string shutdown_service_disable_param("--dont-shutdown-service"); + std::string numbers_of_messages("--number-of-messages"); + std::string help("--help"); + + int i = 1; + while (i < argc) + { + if(tcp_enable == argv[i]) + { + use_tcp = true; + } + else if(udp_enable == argv[i]) + { + use_tcp = false; + } + else if(sync_enable == argv[i]) + { + call_service_sync = true; + } + else if(async_enable == argv[i]) + { + call_service_sync = false; + } + else if(sliding_window_size_param == argv[i] && i + 1 < argc) + { + i++; + std::stringstream converter(argv[i]); + converter >> sliding_window_size; + } + else if(max_payload_size_param == argv[i] && i + 1 < argc) + { + i++; + if(std::string("UDS") == argv[i]) + { + max_payload_size = payloadsize::UDS; + } + else if(std::string("TCP") == argv[i]) + { + max_payload_size = payloadsize::TCP; + } + else if(std::string("UDP") == argv[i]) + { + max_payload_size = payloadsize::UDP; + } + else { + max_payload_size = payloadsize::USER_SPECIFIED; + std::stringstream converter(argv[i]); + converter >> user_defined_max_payload; + } + } + else if (numbers_of_messages == argv[i]) { + i++; + std::stringstream converter(argv[i]); + converter >> number_of_messages_to_send; + } + else if(shutdown_service_disable_param == argv[i]) + { + shutdown_service_at_end = false; + } + else if(help == argv[i]) + { + VSOMEIP_INFO << "Parameters:\n" + << "--tcp: Send messages via TCP\n" + << "--udp: Send messages via UDP (default)\n" + << "--sync: Wait for acknowledge before sending next message (default)\n" + << "--async: Send multiple messages w/o waiting for" + " acknowledge of service\n" + << "--sliding-window-size: Number of messages to send before waiting " + "for acknowledge of service. Default: " << sliding_window_size << "\n" + << "--max-payload-size: limit the maximum payloadsize of send requests. One of {" + "UDS (=" << VSOMEIP_MAX_LOCAL_MESSAGE_SIZE << "byte), " + "UDP (=" << VSOMEIP_MAX_UDP_MESSAGE_SIZE << "byte), " + "TCP (=" << VSOMEIP_MAX_TCP_MESSAGE_SIZE << "byte)}, default: UDS\n" + << "--dont-shutdown-service: Don't shutdown the service upon " + "finishing of the payload test\n" + << "--number-of-messages: Number of messages to send per payload size iteration\n" + << "--help: print this help"; + } + i++; + } + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/payload_tests/payload_test_client.hpp b/test/network_tests/payload_tests/payload_test_client.hpp new file mode 100644 index 0000000..2757d00 --- /dev/null +++ b/test/network_tests/payload_tests/payload_test_client.hpp @@ -0,0 +1,71 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef PAYLOADTESTCLIENT_HPP_ +#define PAYLOADTESTCLIENT_HPP_ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "../someip_test_globals.hpp" + +#include "stopwatch.hpp" + +class payload_test_client +{ +public: + payload_test_client(bool _use_tcp, bool _call_service_sync, std::uint32_t _sliding_window_size); + bool init(); + void start(); + void stop(); + void join_sender_thread(); + void on_state(vsomeip::state_type_e _state); + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available); + void on_message(const std::shared_ptr &_response); + void send(); + void run(); + +private: + void print_throughput(); + void send_messages_sync(std::unique_lock& lk); + void send_messages_async(std::unique_lock& lk); + void shutdown_service(); + std::uint32_t get_max_allowed_payload(); + +private: + std::shared_ptr app_; + std::shared_ptr request_; + bool call_service_sync_; + std::uint32_t sliding_window_size_; + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + bool is_available_; + const std::uint32_t number_of_messages_to_send_; + std::uint32_t number_of_sent_messages_; + std::uint32_t number_of_sent_messages_total_; + std::uint32_t number_of_acknowledged_messages_; + + std::uint32_t current_payload_size_; + + stop_watch watch_; + + bool all_msg_acknowledged_; + std::mutex all_msg_acknowledged_mutex_; + std::condition_variable all_msg_acknowledged_cv_; + + std::thread sender_; + +}; + +#endif /* PAYLOADTESTCLIENT_HPP_ */ diff --git a/test/network_tests/payload_tests/payload_test_service.cpp b/test/network_tests/payload_tests/payload_test_service.cpp new file mode 100644 index 0000000..5cace17 --- /dev/null +++ b/test/network_tests/payload_tests/payload_test_service.cpp @@ -0,0 +1,185 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "payload_test_service.hpp" + +// this variables are changed via cmdline parameters + +static bool check_payload = true; + +payload_test_service::payload_test_service() : + app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + blocked_(false), + number_of_received_messages_(0), + offer_thread_(std::bind(&payload_test_service::run, this)) +{ +} + +bool payload_test_service::init() +{ + std::lock_guard its_lock(mutex_); + + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, + std::bind(&payload_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, + std::bind(&payload_test_service::on_message_shutdown, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&payload_test_service::on_state, this, + std::placeholders::_1)); + return true; +} + +void payload_test_service::start() +{ + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void payload_test_service::stop() +{ + VSOMEIP_INFO << "Stopping..."; + app_->clear_all_handler(); + app_->stop(); +} + +void payload_test_service::join_offer_thread() +{ + offer_thread_.join(); +} + +void payload_test_service::offer() +{ + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void payload_test_service::stop_offer() +{ + app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void payload_test_service::on_state(vsomeip::state_type_e _state) +{ + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : + "deregistered."); + + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + if(!is_registered_) + { + is_registered_ = true; + std::lock_guard its_lock(mutex_); + blocked_ = true; + // "start" the run method thread + condition_.notify_one(); + } + } + else + { + is_registered_ = false; + } +} + +void payload_test_service::on_message(const std::shared_ptr& _request) +{ + number_of_received_messages_++; + if(number_of_received_messages_ % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS == 0) + { + VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _request->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _request->get_session() << "] payload size [byte]:" + << std::dec << _request->get_payload()->get_length(); + } + + ASSERT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _request->get_service()); + ASSERT_EQ(vsomeip_test::TEST_SERVICE_METHOD_ID, _request->get_method()); + + // Check the protocol version this shall be set to 0x01 according to the spec. + // TR_SOMEIP_00052 + ASSERT_EQ(0x01, _request->get_protocol_version()); + // Check the message type this shall be 0xx (REQUEST) according to the spec. + // TR_SOMEIP_00055 + ASSERT_EQ(vsomeip::message_type_e::MT_REQUEST, _request->get_message_type()); + + if (check_payload) { + std::shared_ptr pl = _request->get_payload(); + vsomeip::byte_t* pl_ptr = pl->get_data(); + for (vsomeip::length_t i = 0; i < pl->get_length(); i++) + { + ASSERT_EQ(vsomeip_test::PAYLOAD_TEST_DATA, *(pl_ptr+i)); + } + } + + // send response + std::shared_ptr its_response = + vsomeip::runtime::get()->create_response(_request); + + app_->send(its_response); +} + +void payload_test_service::on_message_shutdown( + const std::shared_ptr& _request) +{ + (void)_request; + VSOMEIP_INFO << "Shutdown method was called, going down now."; + stop(); +} + +void payload_test_service::run() +{ + std::unique_lock its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); + + offer(); +} + +TEST(someip_payload_test, send_response_for_every_request) +{ + payload_test_service test_service; + if (test_service.init()) { + test_service.start(); + test_service.join_offer_thread(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + std::string help("--help"); + std::string check("--do-not-check-payload"); + + int i = 1; + while (i < argc) + { + if(help == argv[i]) + { + VSOMEIP_INFO << "Parameters:\n" + << "--help: print this help\n" + << "--do-not-check-payload: Don't verify payload data " + << "-> Use this flag for performance measurements!"; + } else if (check == argv[i]) { + check_payload = false; + } + i++; + } + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/payload_tests/payload_test_service.hpp b/test/network_tests/payload_tests/payload_test_service.hpp new file mode 100644 index 0000000..9054fd9 --- /dev/null +++ b/test/network_tests/payload_tests/payload_test_service.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef PAYLOADTESTSERVICE_HPP_ +#define PAYLOADTESTSERVICE_HPP_ +#include + +#include + +#include +#include +#include +#include + +#include "../someip_test_globals.hpp" + +class payload_test_service +{ +public: + payload_test_service(); + bool init(); + void start(); + void stop(); + void offer(); + void stop_offer(); + void join_offer_thread(); + void on_state(vsomeip::state_type_e _state); + void on_message(const std::shared_ptr &_request); + void on_message_shutdown(const std::shared_ptr &_request); + void run(); + +private: + std::shared_ptr app_; + bool is_registered_; + + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + std::uint32_t number_of_received_messages_; + std::thread offer_thread_; +}; + +#endif /* PAYLOADTESTSERVICE_HPP_ */ diff --git a/test/network_tests/payload_tests/stopwatch.cpp b/test/network_tests/payload_tests/stopwatch.cpp new file mode 100644 index 0000000..83506f4 --- /dev/null +++ b/test/network_tests/payload_tests/stopwatch.cpp @@ -0,0 +1,38 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "stopwatch.hpp" + +#include +#include + + +#define USEC_PER_SEC 1000000ULL +#define NSEC_PER_USEC 1000ULL + + +stop_watch::usec_t stop_watch::get_total_elapsed_microseconds() const { + usec_t elapsed = total_elapsed_; + + if (started_) + elapsed += get_elapsed(); + + return elapsed; +} + +stop_watch::usec_t stop_watch::get_total_elapsed_seconds() const { + return get_total_elapsed_microseconds() / USEC_PER_SEC; +} + +stop_watch::usec_t stop_watch::now() { + struct timespec ts; + + const int ret = clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + assert(!ret); + static_cast(ret); // prevent warning in release build + + return (usec_t) ts.tv_sec * USEC_PER_SEC + (usec_t) ts.tv_nsec / NSEC_PER_USEC; +} + diff --git a/test/network_tests/payload_tests/stopwatch.hpp b/test/network_tests/payload_tests/stopwatch.hpp new file mode 100644 index 0000000..5917e12 --- /dev/null +++ b/test/network_tests/payload_tests/stopwatch.hpp @@ -0,0 +1,58 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef STOP_WATCH_H_ +#define STOP_WATCH_H_ + +#include + + +class stop_watch +{ +public: + typedef uint64_t usec_t; + + stop_watch() : + started_(false), + start_time_point_(0), + total_elapsed_(0) + { + } + + inline void reset() + { + started_ = false; + total_elapsed_ = 0; + } + + inline void start() + { + start_time_point_ = now(); + started_ = true; + } + + inline void stop() + { + total_elapsed_ += get_elapsed(); + started_ = false; + } + + usec_t get_total_elapsed_microseconds() const; + usec_t get_total_elapsed_seconds() const; + +private: + inline usec_t get_elapsed() const + { + return now() - start_time_point_; + } + + static usec_t now(); + + bool started_; + usec_t start_time_point_; + usec_t total_elapsed_; +}; + +#endif // STOP_WATCH_H_ diff --git a/test/network_tests/pending_subscription_tests/conf/pending_subscription_test_master.json.in b/test/network_tests/pending_subscription_tests/conf/pending_subscription_test_master.json.in new file mode 100644 index 0000000..5bcbe9a --- /dev/null +++ b/test/network_tests/pending_subscription_tests/conf/pending_subscription_test_master.json.in @@ -0,0 +1,55 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications" : + [ + { + "name" : "pending_subscription_test_service", + "id" : "0xCAFE", + "max_dispatch_time" : "1000" + } + ], + "services": + [ + { + "service":"0x1122", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x1111", + "is_reliable" : "false" + }, + { + "event" : "0x1112", + "is_reliable" : "false" + } + ] + } + ], + "routing":"routingmanagerd", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.23.1", + "port":"30490", + "protocol":"udp", + "cyclic_offer_delay" : "1000" + } +} \ No newline at end of file diff --git a/test/network_tests/pending_subscription_tests/conf/pending_subscription_test_master_starter.sh.in b/test/network_tests/pending_subscription_tests/conf/pending_subscription_test_master_starter.sh.in new file mode 100755 index 0000000..dc4b1cd --- /dev/null +++ b/test/network_tests/pending_subscription_tests/conf/pending_subscription_test_master_starter.sh.in @@ -0,0 +1,72 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +FAIL=0 + +if [ $# -lt 1 ] +then + echo "Please pass a test mode to this script." + echo "For example: $0 SUSCRIBE" + echo "Valid subscription types include:" + echo " [SUBSCRIBE, SUBSCRIBE_UNSUBSCRIBE, UNSUBSCRIBE, SUBSCRIBE_UNSUBSCRIBE_NACK, SUBSCRIBE_UNSUBSCRIBE_SAME_PORT, SUBSCRIBE_RESUBSCRIBE_MIXED, SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE, REQUEST_TO_SD]" + exit 1 +fi +TESTMODE=$1 +export VSOMEIP_CONFIGURATION=pending_subscription_test_master.json +# start daemon +../../examples/routingmanagerd/./routingmanagerd & +PID_VSOMEIPD=$! +# Start the services +./pending_subscription_test_service $1 & +PID_SERIVCE=$! + +sleep 1 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "Waiting for 5s" + sleep 5 + echo "starting offer test on slave LXC offer_test_external_slave_starter.sh" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./pending_subscription_test_sd_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $TESTMODE\"" & + echo "remote ssh pid: $!" +elif [ ! -z "$USE_DOCKER" ]; then + echo "Waiting for 5s" + sleep 5 + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./pending_subscription_test_sd_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $TESTMODE" & +else +cat < +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include "../../implementation/utility/include/byteorder.hpp" +#include "../../implementation/message/include/deserializer.hpp" +#include "../../implementation/service_discovery/include/service_discovery.hpp" +#include "../../implementation/service_discovery/include/message_impl.hpp" +#include "../../implementation/service_discovery/include/constants.hpp" +#include "../../implementation/service_discovery/include/enumeration_types.hpp" +#include "../../implementation/service_discovery/include/eventgroupentry_impl.hpp" +#include "../../implementation/message/include/message_impl.hpp" +#include "pending_subscription_test_globals.hpp" + +static char* remote_address; +static char* local_address; + +class pending_subscription : public ::testing::Test { +public: + pending_subscription() : + work_(std::make_shared(io_)), + io_thread_(std::bind(&pending_subscription::io_run, this)) {} +protected: + + void TearDown() { + work_.reset(); + io_thread_.join(); + io_.stop(); + } + + void io_run() { + io_.run(); + } + + boost::asio::io_context io_; + std::shared_ptr work_; + std::thread io_thread_; +}; + +/* + * @test Send 16 subscriptions to the service and check that every + * subscription is answered with an SubscribeEventgroupAck entry by the service. + * Check that the subscription is active at the end of the test and check that + * the notifications send by the service receive the client + */ +TEST_F(pending_subscription, send_multiple_subscriptions) +{ + std::promise trigger_notifications; + + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); + udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); + + std::thread receive_thread([&](){ + bool keep_receiving(true); + std::vector receive_buffer(4096); + std::vector its_received_events; + std::uint32_t subscribe_acks_receiveid = 0; + std::uint32_t events_received = 0; + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + } else { + + std::uint32_t its_pos = 0; + + while (bytes_transferred > 0) { + const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], + receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], + receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); + its_pos += its_message_size; + bytes_transferred -= its_message_size; + + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(2u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); + EXPECT_EQ(3u, e->get_ttl()); + EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); + EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id || + its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id+1); + subscribe_acks_receiveid++; + } + } + EXPECT_EQ(0u, sd_msg.get_options().size()); + } else { // non-sd-message + vsomeip::message_impl msg; + EXPECT_TRUE(msg.deserialize(&its_deserializer)); + if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); + EXPECT_EQ(0x2222, msg.get_client()); + } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + its_received_events.push_back(msg.get_method()); + if (its_received_events.size() == 2) { + EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[0]); + EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[1]); + events_received = 2; + } + EXPECT_EQ(1u, msg.get_payload()->get_length()); + EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(0x0, msg.get_client()); + } + } + } + if (subscribe_acks_receiveid == 30) { // all subscribeAcks received + trigger_notifications.set_value(true); + subscribe_acks_receiveid++; // don't set promise value again + } + if (its_received_events.size() == 2 && events_received == 2) { + // all events received as well + keep_receiving = false; + } + } + } + }); + + std::thread send_thread([&]() { + try { + std::uint8_t its_subscribe_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x40, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, // length entries array + 0x06, 0x00, 0x00, 0x10, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x10, 0x00, // eventgroup + 0x06, 0x00, 0x00, 0x10, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x10, 0x01, // eventgroup 2 + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // ip address + 0x00, 0x11, 0x77, 0x1a + }; + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_subscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + for (int var = 0; var < 15; ++var) { + udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); + ++its_subscribe_message[11]; + } + + + if (std::future_status::timeout == trigger_notifications.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive all SubscribeAcks within time"; + } else { + // call notify method + std::uint8_t trigger_notifications_call[] = { + 0x11, 0x22, 0x42, 0x42, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x01, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); + } + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x11, 0x22, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); + } catch (...) { + ASSERT_FALSE(true); + } + + }); + + send_thread.join(); + receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); +} + +/* + * @test Send 16 subscriptions to the service while alternating between Subscribe + * and Unsubscribe and check that every SubscribeEventgroupEntry (ttl > 0) + * is answered with an SubscribeEventgroupAck entry by the service. + * Check that the subscription is active at the end of the test and check that + * the notifications send by the service receive the client + */ +TEST_F(pending_subscription, send_alternating_subscribe_unsubscribe) +{ + std::promise trigger_notifications; + + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); + udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); + + std::thread receive_thread([&](){ + const std::uint32_t expected_acks(8); + std::atomic acks_received(0); + + const std::uint32_t expected_responses(1); + std::atomic responses_received(0); + + const std::uint32_t expected_notifications(2); + std::atomic notifications_received(0); + + bool triggered_notifications(false); + + std::vector receive_buffer(4096); + std::vector its_received_events; + + bool keep_receiving(true); + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + acks_received = expected_acks; + responses_received = expected_responses; + ADD_FAILURE() << __func__ << " error: " << error.message(); + } else { + #if 0 + std::stringstream str; + for (size_t i = 0; i < bytes_transferred; i++) { + str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; + } + std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; + #endif + std::uint32_t its_pos = 0; + + while (bytes_transferred > 0) { + const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], + receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], + receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); + its_pos += its_message_size; + bytes_transferred -= its_message_size; + + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(2u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); + EXPECT_EQ(16u, e->get_ttl()); + EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); + EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id || + its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id+1); + } + } + EXPECT_EQ(0u, sd_msg.get_options().size()); + acks_received++; + } else { // non-sd-message + vsomeip::message_impl msg; + EXPECT_TRUE(msg.deserialize(&its_deserializer)); + if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); + EXPECT_EQ(0x2222, msg.get_client()); + responses_received++; + } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + its_received_events.push_back(msg.get_method()); + if (its_received_events.size() == 2) { + EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[0]); + EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[1]); + } + EXPECT_EQ(1u, msg.get_payload()->get_length()); + EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(0x0, msg.get_client()); + notifications_received++; + } + } + + if (!triggered_notifications && acks_received == expected_acks) { // all subscribeAcks received + trigger_notifications.set_value(true); + triggered_notifications = true; + } + } + } + if (acks_received == expected_acks && + responses_received == expected_responses && + notifications_received == expected_notifications) { + keep_receiving = false; + } + } + + + EXPECT_EQ(expected_acks, acks_received); + EXPECT_EQ(expected_responses, responses_received); + EXPECT_EQ(expected_notifications, notifications_received); + }); + + std::thread send_thread([&]() { + try { + std::uint8_t its_subscribe_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x40, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, // length entries array + 0x06, 0x00, 0x00, 0x10, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL + 0x00, 0x00, 0x10, 0x00, // eventgroup + 0x06, 0x00, 0x00, 0x10, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL + 0x00, 0x00, 0x10, 0x01, // eventgroup 2 + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // ip address + 0x00, 0x11, 0x77, 0x1a + }; + + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_subscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + for (int var = 0; var < 15; ++var) { + udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); + ++its_subscribe_message[11]; + if (its_subscribe_message[11] % 2) { + its_subscribe_message[35] = 16; + its_subscribe_message[51] = 16; + } else { + its_subscribe_message[35] = 0; + its_subscribe_message[51] = 0; + } + } + + if (std::future_status::timeout == trigger_notifications.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive all SubscribeAcks within time"; + } else { + // call notify method + std::uint8_t trigger_notifications_call[] = { + 0x11, 0x22, 0x42, 0x42, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x01, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); + } + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x11, 0x22, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); + } catch (...) { + ASSERT_FALSE(true); + } + + }); + + send_thread.join(); + receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); +} + +/* + * @test Send 16 subscriptions to the service while only two contain a + * SubscribeEventgroupEntry and the rest contain StopSubscribeEventgroupEntries + * and check that all subscriptions with SubscribeEventgroupEntries are + * answered with an SubscribeEventgroupAck entry by the service. + * Check that the subscription is active at the end of the test and check that + * the notifications send by the service receive the client + */ +TEST_F(pending_subscription, send_multiple_unsubscriptions) +{ + std::promise trigger_notifications; + + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); + udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); + + std::thread receive_thread([&](){ + const std::uint32_t expected_acks(2); + std::atomic acks_received(0); + + const std::uint32_t expected_responses(1); + std::atomic responses_received(0); + + const std::uint32_t expected_notifications(2); + std::atomic notifications_received(0); + + bool triggered_notifications(false); + + std::vector receive_buffer(4096); + std::vector its_received_events; + + bool keep_receiving(true); + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + acks_received = expected_acks; + responses_received = expected_responses; + ADD_FAILURE() << __func__ << " error: " << error.message(); + } else { + #if 0 + std::stringstream str; + for (size_t i = 0; i < bytes_transferred; i++) { + str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; + } + std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; + #endif + std::uint32_t its_pos = 0; + while (bytes_transferred > 0) { + const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], + receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], + receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); + its_pos += its_message_size; + bytes_transferred -= its_message_size; + + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(2u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); + EXPECT_EQ(16u, e->get_ttl()); + EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); + EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id || + its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id+1); + } + } + EXPECT_EQ(0u, sd_msg.get_options().size()); + acks_received++; + } else { // non-sd-message + vsomeip::message_impl msg; + EXPECT_TRUE(msg.deserialize(&its_deserializer)); + if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); + EXPECT_EQ(0x2222, msg.get_client()); + responses_received++; + } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + its_received_events.push_back(msg.get_method()); + if (its_received_events.size() == 2) { + EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[0]); + EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[1]); + } + EXPECT_EQ(1u, msg.get_payload()->get_length()); + EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(0x0, msg.get_client()); + notifications_received++; + } + } + } + if (!triggered_notifications && acks_received == expected_acks) { // all subscribeAcks received + trigger_notifications.set_value(true); + triggered_notifications = true; + } + } + if (acks_received == expected_acks && + responses_received == expected_responses && + notifications_received == expected_notifications) { + std::cerr << "every thing received" << std::endl; + keep_receiving = false; + } + } + + EXPECT_EQ(expected_acks, acks_received); + EXPECT_EQ(expected_responses, responses_received); + EXPECT_EQ(expected_notifications, notifications_received); + }); + + std::thread send_thread([&]() { + try { + std::uint8_t its_subscribe_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x40, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, // length entries array + 0x06, 0x00, 0x00, 0x10, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL + 0x00, 0x00, 0x10, 0x00, // eventgroup + 0x06, 0x00, 0x00, 0x10, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL + 0x00, 0x00, 0x10, 0x01, // eventgroup 2 + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // ip address + 0x00, 0x11, 0x77, 0x1a + }; + + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_subscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + for (int var = 0; var < 15; ++var) { + if (its_subscribe_message[11] == 15 || its_subscribe_message[11] == 0x1) { + its_subscribe_message[35] = 16; + its_subscribe_message[51] = 16; + } else { + its_subscribe_message[35] = 0; + its_subscribe_message[51] = 0; + } + udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); + ++its_subscribe_message[11]; + } + + if (std::future_status::timeout == trigger_notifications.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive all SubscribeAcks within time"; + } else { + // call notify method + std::uint8_t trigger_notifications_call[] = { + 0x11, 0x22, 0x42, 0x42, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x01, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); + } + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x11, 0x22, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); + } catch (...) { + ASSERT_FALSE(true); + } + + }); + + send_thread.join(); + receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); +} + +/* + * @test Send 16 subscriptions to the service and check that every second + * subscription is answered with an SubscribeEventgroupNack entry by the service. + * Check that the subscription is active at the end of the test and check that + * the notifications send by the service receive the client + */ +TEST_F(pending_subscription, send_alternating_subscribe_nack_unsubscribe) +{ + std::promise trigger_notifications; + + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); + udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); + + std::thread receive_thread([&](){ + const std::uint32_t expected_acks(8); + std::atomic acks_received(0); + + const std::uint32_t expected_nacks(8); + std::atomic nacks_received(0); + + const std::uint32_t expected_responses(1); + std::atomic responses_received(0); + + const std::uint32_t expected_notifications(2); + std::atomic notifications_received(0); + + bool triggered_notifications(false); + bool keep_receiving(true); + + std::vector receive_buffer(4096); + std::vector its_received_events; + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + acks_received = expected_acks; + responses_received = expected_responses; + nacks_received = expected_nacks; + ADD_FAILURE() << __func__ << " error: " << error.message(); + } else { + #if 0 + std::stringstream str; + for (size_t i = 0; i < bytes_transferred; i++) { + str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; + } + std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; + #endif + std::uint32_t its_pos = 0; + while (bytes_transferred > 0) { + const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], + receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], + receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); + its_pos += its_message_size; + bytes_transferred -= its_message_size; + + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(2u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); + if (e->get_ttl()) { + EXPECT_EQ(16u, e->get_ttl()); + acks_received++; + } else { + EXPECT_EQ(0u, e->get_ttl()); + nacks_received++; + } + EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); + EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id || + its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id+1); + } + } + EXPECT_EQ(0u, sd_msg.get_options().size()); + } else { // non-sd-message + vsomeip::message_impl msg; + EXPECT_TRUE(msg.deserialize(&its_deserializer)); + if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); + EXPECT_EQ(0x2222, msg.get_client()); + responses_received++; + } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + its_received_events.push_back(msg.get_method()); + if (its_received_events.size() == 2) { + EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[0]); + EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[1]); + } + EXPECT_EQ(1u, msg.get_payload()->get_length()); + EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(0x0, msg.get_client()); + notifications_received++; + } + } + + + if (!triggered_notifications && acks_received == expected_acks && + nacks_received == expected_nacks) { // all subscribeAcks received + trigger_notifications.set_value(true); + triggered_notifications = true; + } + } + } + if (nacks_received == expected_nacks && + acks_received == expected_acks && + notifications_received == expected_notifications && + responses_received == expected_responses) { + keep_receiving = false; + } + } + + EXPECT_EQ(expected_acks, acks_received); + EXPECT_EQ(expected_nacks, nacks_received); + EXPECT_EQ(expected_responses, responses_received); + EXPECT_EQ(expected_notifications, notifications_received); + }); + + std::thread send_thread([&]() { + try { + std::uint8_t its_subscribe_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x40, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, // length entries array + 0x06, 0x00, 0x00, 0x10, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL + 0x00, 0x00, 0x10, 0x00, // eventgroup + 0x06, 0x00, 0x00, 0x10, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL + 0x00, 0x00, 0x10, 0x01, // eventgroup 2 + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // ip address + 0x00, 0x11, 0x77, 0x1a + }; + + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_subscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + for (int var = 0; var < 15; ++var) { + udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); + ++its_subscribe_message[11]; + if (its_subscribe_message[11] % 2) { + its_subscribe_message[35] = 16; + its_subscribe_message[51] = 16; + } else { + its_subscribe_message[35] = 0; + its_subscribe_message[51] = 0; + } + } + + if (std::future_status::timeout == trigger_notifications.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive all SubscribeAcks within time"; + } else { + // call notify method + std::uint8_t trigger_notifications_call[] = { + 0x11, 0x22, 0x42, 0x42, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x01, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); + } + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x11, 0x22, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); + } catch (...) { + ASSERT_FALSE(true); + } + + }); + + send_thread.join(); + receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); +} + +/* + * @test Send 16 subscriptions containing an UDP and TCP endpoint option + * to the service while alternating between Subscribe + * and Unsubscribe and check that every SubscribeEventgroupEntry (ttl > 0) + * is answered with an SubscribeEventgroupAck entry by the service. + * Check that the subscription is active at the end of the test and check that + * the notifications send by the service receive the client + */ +TEST_F(pending_subscription, send_alternating_subscribe_unsubscribe_same_port) +{ + std::promise trigger_notifications; + std::promise tcp_connected; + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); + udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); + boost::asio::ip::tcp::socket tcp_socket(io_, + boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 30490)); + tcp_socket.set_option(boost::asio::socket_base::reuse_address(true)); + tcp_socket.set_option(boost::asio::socket_base::linger(true, 0)); + + std::thread receive_thread([&](){ + const std::uint32_t expected_acks(8); + std::atomic acks_received(0); + + const std::uint32_t expected_responses(1); + std::atomic responses_received(0); + + const std::uint32_t expected_notifications(2); + std::atomic notifications_received(0); + + bool triggered_notifications(false); + + std::vector receive_buffer(4096); + std::vector its_received_events; + + boost::system::error_code ec; + tcp_socket.connect(boost::asio::ip::tcp::endpoint( + boost::asio::ip::address::from_string(remote_address), 40001), ec); + ASSERT_EQ(0, ec.value()); + tcp_connected.set_value(); + + bool keep_receiving(true); + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + acks_received = expected_acks; + responses_received = expected_responses; + ADD_FAILURE() << __func__ << " error: " << error.message(); + } else { + + std::uint32_t its_pos = 0; + + while (bytes_transferred > 0) { + const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], + receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], + receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); + its_pos += its_message_size; + bytes_transferred -= its_message_size; + + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(2u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); + EXPECT_EQ(16u, e->get_ttl()); + EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); + EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id || + its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id+1); + } + } + EXPECT_EQ(0u, sd_msg.get_options().size()); + acks_received++; + } else { // non-sd-message + vsomeip::message_impl msg; + EXPECT_TRUE(msg.deserialize(&its_deserializer)); + if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); + EXPECT_EQ(0x2222, msg.get_client()); + responses_received++; + } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + its_received_events.push_back(msg.get_method()); + if (its_received_events.size() == 2) { + EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[0]); + EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[1]); + } + EXPECT_EQ(1u, msg.get_payload()->get_length()); + EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(0x0, msg.get_client()); + notifications_received++; + } + } + + + if (!triggered_notifications && acks_received == expected_acks) { // all subscribeAcks received + trigger_notifications.set_value(true); + triggered_notifications = true; + } + } + } + if (acks_received == expected_acks && + responses_received == expected_responses && + notifications_received == expected_notifications) { + keep_receiving = false; + } + } + + + EXPECT_EQ(expected_acks, acks_received); + EXPECT_EQ(expected_responses, responses_received); + EXPECT_EQ(expected_notifications, notifications_received); + }); + + std::thread send_thread([&]() { + if (std::future_status::timeout == tcp_connected.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't establish tcp connection within time"; + } + + try { + std::uint8_t its_subscribe_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x4C, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, // length entries array + 0x06, 0x00, 0x00, 0x20, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL + 0x00, 0x00, 0x10, 0x00, // eventgroup + 0x06, 0x00, 0x00, 0x20, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL + 0x00, 0x00, 0x10, 0x01, // eventgroup 2 + 0x00, 0x00, 0x00, 0x18, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // ip address + 0x00, 0x11, 0x77, 0x1a, + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // ip address + 0x00, 0x06, 0x77, 0x1a + }; + + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_subscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); + std::memcpy(&its_subscribe_message[76], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + for (int var = 0; var < 15; ++var) { + udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); + ++its_subscribe_message[11]; + if (its_subscribe_message[11] % 2) { + its_subscribe_message[35] = 16; + its_subscribe_message[51] = 16; + } else { + its_subscribe_message[35] = 0; + its_subscribe_message[51] = 0; + } + } + + if (std::future_status::timeout == trigger_notifications.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive all SubscribeAcks within time"; + } else { + // call notify method + std::uint8_t trigger_notifications_call[] = { + 0x11, 0x22, 0x42, 0x42, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x01, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); + } + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x11, 0x22, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); + } catch (...) { + ASSERT_FALSE(true); + } + + }); + + send_thread.join(); + receive_thread.join(); + boost::system::error_code ec; + tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket.close(ec); + udp_socket.close(ec); +} + +/* + * @test Send a subscription as single message and afterwards send a + * resubscription containing a new subscription in the same message and check + * to receive initial event + */ +TEST_F(pending_subscription, subscribe_resubscribe_mixed) +{ + std::promise first_initial_event_received; + std::promise second_initial_event_received; + + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); + udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); + + std::thread receive_thread([&](){ + std::vector receive_buffer(4096); + std::vector its_received_events; + + const std::uint32_t expected_acks(3); + std::atomic acks_received(0); + + const std::uint32_t expected_responses(1); + std::atomic responses_received(0); + + const std::uint32_t expected_notifications(2); + std::atomic notifications_received(0); + + bool keep_receiving(true); + bool first_initial_event_checked(false); + bool second_initial_event_checked(false); + + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transfered = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + } else { + + std::uint32_t its_pos = 0; + + while (bytes_transfered > 0) { + const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], + receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], + receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); + its_pos += its_message_size; + bytes_transfered -= its_message_size; + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_GE(2u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); + EXPECT_EQ(3u, e->get_ttl()); + EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); + EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { + acks_received++; + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id || + its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id+1); + } + } + EXPECT_EQ(0u, sd_msg.get_options().size()); + } else { // non-sd-message + vsomeip::message_impl msg; + EXPECT_TRUE(msg.deserialize(&its_deserializer)); + if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); + EXPECT_EQ(0x2222, msg.get_client()); + responses_received++; + } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + its_received_events.push_back(msg.get_method()); + if (its_received_events.size() == 2) { + EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[0]); + EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[1]); + } + EXPECT_EQ(1u, msg.get_payload()->get_length()); + EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(0x0, msg.get_client()); + notifications_received++; + } + } + + if (!first_initial_event_checked && notifications_received == 1) { + EXPECT_EQ(1u, its_received_events.size()); + EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[0]); + // all subscribeAcks and one initial event of first event received + first_initial_event_received.set_value(); + first_initial_event_checked = true; + } + + if (!second_initial_event_checked && notifications_received == 2) { // events were received as well + // all subscribeAcks and one initial event of second event received + EXPECT_EQ(2u, its_received_events.size()); + EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[0]); + EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[1]); + second_initial_event_received.set_value(); + second_initial_event_checked = true; + } + if (notifications_received == 2 && responses_received == 1) { + keep_receiving = false; + } + } + } + } + EXPECT_EQ(expected_acks, acks_received); + EXPECT_EQ(expected_notifications, notifications_received); + EXPECT_EQ(expected_responses, responses_received); + }); + + std::thread send_thread([&]() { + try { + // call notify method to ensure to receive initial events + std::uint8_t trigger_notifications_call[] = { + 0x11, 0x22, 0x42, 0x42, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x01, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); + + std::uint8_t its_subscribe_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x06, 0x00, 0x00, 0x10, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x10, 0x01, // eventgroup + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // ip address + 0x00, 0x11, 0x77, 0x1a + }; + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_subscribe_message[48], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + + udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); + + + + if (std::future_status::timeout == first_initial_event_received.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive all SubscribeAck of first subscription within time"; + } + + // send second subscription with resubscription and new subscription + std::uint8_t its_subscribe_resubscribe_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x40, // length + 0x00, 0x00, 0x00, 0x02, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, // length entries array + 0x06, 0x00, 0x00, 0x10, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x10, 0x00, // eventgroup + 0x06, 0x00, 0x00, 0x10, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x10, 0x01, // eventgroup 2 + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // ip address + 0x00, 0x11, 0x77, 0x1a + }; + std::memcpy(&its_subscribe_resubscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); + udp_socket.send_to(boost::asio::buffer(its_subscribe_resubscribe_message), target_sd); + + if (std::future_status::timeout == second_initial_event_received.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive all SubscribeAck of second subscription within time"; + } + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x11, 0x22, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); + } catch (...) { + ASSERT_FALSE(true); + } + + }); + + send_thread.join(); + receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); +} + +/* + * @test Send a SD message containing a Subscription followed by a StopSubscribe + * Subscribe entry to the same service. Check to receive an initial event + */ +TEST_F(pending_subscription, send_subscribe_stop_subscribe_subscribe) +{ + std::promise trigger_notifications; + std::promise tcp_connected; + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); + udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); + boost::asio::ip::tcp::socket tcp_socket(io_, + boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 30490)); + tcp_socket.set_option(boost::asio::socket_base::reuse_address(true)); + tcp_socket.set_option(boost::asio::socket_base::linger(true, 0)); + + std::thread receive_thread([&](){ + const std::uint32_t expected_acks(2); + std::atomic acks_received(0); + + const std::uint32_t expected_responses(1); + std::atomic responses_received(0); + + const std::uint32_t expected_notifications(1); + std::atomic notifications_received(0); + + bool triggered_notifications(false); + + std::vector receive_buffer(4096); + std::vector its_received_events; + + boost::system::error_code ec; + tcp_socket.connect(boost::asio::ip::tcp::endpoint( + boost::asio::ip::address::from_string(remote_address), 40001), ec); + ASSERT_EQ(0, ec.value()); + tcp_connected.set_value(); + + bool keep_receiving(true); + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + acks_received = expected_acks; + responses_received = expected_responses; + ADD_FAILURE() << __func__ << " error: " << error.message(); + } else { + + std::uint32_t its_pos = 0; + + while (bytes_transferred > 0) { + #if 0 + std::stringstream str; + for (size_t i = 0; i < bytes_transferred; i++) { + str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; + } + std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; + #endif + + const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], + receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], + receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); + its_pos += its_message_size; + bytes_transferred -= its_message_size; + + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(1u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); + EXPECT_EQ(16u, e->get_ttl()); + EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); + EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id); + } + } + EXPECT_EQ(0u, sd_msg.get_options().size()); + acks_received++; + } else { // non-sd-message + vsomeip::message_impl msg; + EXPECT_TRUE(msg.deserialize(&its_deserializer)); + if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); + EXPECT_EQ(0x2222, msg.get_client()); + responses_received++; + } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + its_received_events.push_back(msg.get_method()); + EXPECT_EQ(1u, its_received_events.size()); + EXPECT_EQ(1u, msg.get_payload()->get_length()); + EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(0x0, msg.get_client()); + notifications_received++; + } + } + + if (!triggered_notifications && acks_received == expected_acks) { // all subscribeAcks received + trigger_notifications.set_value(true); + triggered_notifications = true; + } + } + if (acks_received == expected_acks && + responses_received == expected_responses && + notifications_received == expected_notifications) { + keep_receiving = false; + } + } + } + EXPECT_EQ(expected_acks, acks_received); + EXPECT_EQ(expected_responses, responses_received); + EXPECT_EQ(expected_notifications, notifications_received); + }); + + std::thread send_thread([&]() { + if (std::future_status::timeout == tcp_connected.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't establish tcp connection within time"; + } + + try { + std::uint8_t its_normal_subscribe_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x06, 0x00, 0x00, 0x10, // subscribe Eventgroup entry + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL + 0x00, 0x00, 0x10, 0x00, // eventgroup + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // ip address + 0x00, 0x11, 0x77, 0x1a + }; + std::uint8_t its_subscribe_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x50, // length + 0x00, 0x00, 0x00, 0x02, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, // length entries array + 0x06, 0x00, 0x00, 0x10, // subscribe Eventgroup entry + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL + 0x00, 0x00, 0x10, 0x00, // eventgroup + 0x06, 0x00, 0x00, 0x10, // Stop subscribe Eventgroup entry + 0x11, 0x22, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, + 0x06, 0x00, 0x00, 0x10, // subscribe Eventgroup entry + 0x11, 0x22, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // ip address + 0x00, 0x11, 0x77, 0x1a + }; + + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_subscribe_message[80], &its_local_address.to_v4().to_bytes()[0], 4); + std::memcpy(&its_normal_subscribe_message[48], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + + udp_socket.send_to(boost::asio::buffer(its_normal_subscribe_message), target_sd); + udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); + + if (std::future_status::timeout == trigger_notifications.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive all SubscribeAcks within time"; + } else { + // call notify method + std::uint8_t trigger_notifications_call[] = { + 0x11, 0x22, 0x42, 0x42, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x01, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); + } + + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x11, 0x22, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); + } catch (...) { + ASSERT_FALSE(true); + } + + }); + send_thread.join(); + receive_thread.join(); + boost::system::error_code ec; + tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + tcp_socket.close(ec); + udp_socket.close(ec); +} + +/* + * @test Send a message with message type 0x0 (REQUEST) to the remote SD port + * and check if the remote SD continues to send offers + */ +TEST_F(pending_subscription, send_request_to_sd_port) +{ + std::promise all_offers_received; + + boost::asio::ip::udp::socket udp_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + udp_socket.set_option(boost::asio::ip::multicast::enable_loopback(false)); + udp_socket.set_option(boost::asio::ip::multicast::join_group( + boost::asio::ip::address::from_string("224.0.23.1").to_v4())); + udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); + udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); + + std::thread receive_thread([&](){ + bool keep_receiving(true); + std::vector receive_buffer(4096); + std::vector its_received_events; + + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + } else { + std::uint32_t its_pos = 0; + while (bytes_transferred > 0) { + const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], + receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], + receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); + its_pos += its_message_size; + bytes_transferred -= its_message_size; + + #if 0 + std::stringstream str; + for (size_t i = 0; i < bytes_transferred; i++) { + str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; + } + std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; + #endif + static int offers_received = 0; + static int responses_received = 0; + + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(1u, sd_msg.get_entries().size()); + EXPECT_EQ(2u, sd_msg.get_options().size()); + for (const auto& e : sd_msg.get_entries()) { + EXPECT_TRUE(e->is_service_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); + EXPECT_EQ(0xffffffu, e->get_ttl()); + EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); + EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); + offers_received++; + } + } else { // non-sd-message + vsomeip::message_impl msg; + EXPECT_TRUE(msg.deserialize(&its_deserializer)); + if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); + EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); + EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); + EXPECT_EQ(0x2222, msg.get_client()); + responses_received++; + } + } + + if (responses_received == 1) { // response to shutdown method was received as well + keep_receiving = false; + } else if (offers_received == 3 ) { // all multiple offers received + try { + all_offers_received.set_value(true); + } catch (const std::future_error& e) { + + } + } + } + } + } + }); + + std::thread send_thread([&]() { + try { + std::uint8_t its_subscribe_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x40, // length + 0x00, 0x00, 0x10, 0x01, + 0x01, 0x01, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, // message type is set to 0x0 (REQUEST) + 0x00, 0x00, 0x00, 0x20, // length entries array + 0x06, 0x00, 0x00, 0x10, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x10, 0x00, // eventgroup + 0x06, 0x00, 0x00, 0x10, + 0x11, 0x22, 0x00, 0x01, // service / instance + 0x00, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x10, 0x01, // eventgroup 2 + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // ip address + 0x00, 0x11, 0x77, 0x1a + }; + boost::asio::ip::address its_local_address = + boost::asio::ip::address::from_string(std::string(local_address)); + std::memcpy(&its_subscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); + + boost::asio::ip::udp::socket::endpoint_type target_sd( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30490); + for (int var = 0; var < 15; ++var) { + udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); + ++its_subscribe_message[11]; + } + + + if (std::future_status::timeout == all_offers_received.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive all Offers within time"; + } + + { + // call notify method (but don't expect notifications) to allow + // service to exit + std::uint8_t trigger_notifications_call[] = { + 0x11, 0x22, 0x42, 0x42, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x01, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); + } + + { + // call shutdown method + std::uint8_t shutdown_call[] = { + 0x11, 0x22, 0x14, 0x04, + 0x00, 0x00, 0x00, 0x08, + 0x22, 0x22, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service( + boost::asio::ip::address::from_string(std::string(remote_address)), + 30001); + udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); + } + + } catch (...) { + ASSERT_FALSE(true); + } + + }); + + send_thread.join(); + receive_thread.join(); + boost::system::error_code ec; + udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket.close(ec); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + if(argc < 4) { + std::cerr << "Please pass an target and local IP address and test mode to this binary like: " + << argv[0] << " 10.0.3.1 10.0.3.202 SUBSCRIBE" << std::endl; + std::cerr << "Testmodes are [SUBSCRIBE, SUBSCRIBE_UNSUBSCRIBE, UNSUBSCRIBE]" << std::endl; + exit(1); + } + remote_address = argv[1]; + local_address = argv[2]; + std::string its_testmode = argv[3]; + if (its_testmode == std::string("SUBSCRIBE")) { + ::testing::GTEST_FLAG(filter) = "*send_multiple_subscriptions"; + } else if (its_testmode == std::string("SUBSCRIBE_UNSUBSCRIBE")) { + ::testing::GTEST_FLAG(filter) = "*send_alternating_subscribe_unsubscribe"; + } else if (its_testmode == std::string("UNSUBSCRIBE")) { + ::testing::GTEST_FLAG(filter) = "*send_multiple_unsubscriptions"; + } else if (its_testmode == std::string("SUBSCRIBE_UNSUBSCRIBE_NACK")) { + ::testing::GTEST_FLAG(filter) = "*send_alternating_subscribe_nack_unsubscribe"; + } else if (its_testmode == std::string("SUBSCRIBE_UNSUBSCRIBE_SAME_PORT")) { + ::testing::GTEST_FLAG(filter) = "*send_alternating_subscribe_unsubscribe_same_port"; + } else if (its_testmode == std::string("SUBSCRIBE_RESUBSCRIBE_MIXED")) { + ::testing::GTEST_FLAG(filter) = "*subscribe_resubscribe_mixed"; + } else if (its_testmode == std::string("SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE")) { + ::testing::GTEST_FLAG(filter) = "*send_subscribe_stop_subscribe_subscribe"; + } else if (its_testmode == std::string("REQUEST_TO_SD")) { + ::testing::GTEST_FLAG(filter) = "*send_request_to_sd_port"; + } + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/pending_subscription_tests/pending_subscription_test_service.cpp b/test/network_tests/pending_subscription_tests/pending_subscription_test_service.cpp new file mode 100644 index 0000000..53b2cde --- /dev/null +++ b/test/network_tests/pending_subscription_tests/pending_subscription_test_service.cpp @@ -0,0 +1,389 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "pending_subscription_test_globals.hpp" + +class pending_subscription_test_service { +public: + pending_subscription_test_service(struct pending_subscription_test::service_info _service_info, pending_subscription_test::test_mode_e _testmode) : + service_info_(_service_info), + testmode_(_testmode), + app_(vsomeip::runtime::get()->create_application("pending_subscription_test_service")), + wait_until_registered_(true), + wait_until_shutdown_method_called_(true), + subscription_accepted_asynchronous_(false), + subscription_accepted_synchronous_(false), + offer_thread_(std::bind(&pending_subscription_test_service::run, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&pending_subscription_test_service::on_state, this, + std::placeholders::_1)); + + // offer field + std::set its_eventgroups; + its_eventgroups.insert(_service_info.eventgroup_id); + app_->offer_event(service_info_.service_id, 0x1, + service_info_.event_id, + its_eventgroups, vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + + its_eventgroups.clear(); + its_eventgroups.insert(static_cast(_service_info.eventgroup_id+1u)); + + app_->offer_event(service_info_.service_id, 0x1, + static_cast(service_info_.event_id+1u), + its_eventgroups, vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, service_info_.shutdown_method_id, + std::bind(&pending_subscription_test_service::on_shutdown_method_called, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, service_info_.notify_method_id, + std::bind(&pending_subscription_test_service::on_notify_method_called, this, + std::placeholders::_1)); + + app_->register_async_subscription_handler(service_info_.service_id, + 0x1, service_info_.eventgroup_id, + std::bind(&pending_subscription_test_service::subscription_handler_async, + this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, + std::placeholders::_4, std::placeholders::_5)); + app_->register_subscription_handler(service_info_.service_id, + 0x1, static_cast(service_info_.eventgroup_id+1u), + std::bind(&pending_subscription_test_service::subscription_handler, + this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, + std::placeholders::_4)); + app_->start(); + } + + ~pending_subscription_test_service() { + offer_thread_.join(); + } + + void offer() { + app_->offer_service(service_info_.service_id, 0x1); + } + + void stop() { + app_->stop_offer_service(service_info_.service_id, 0x1); + app_->clear_all_handler(); + app_->stop(); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_shutdown_method_called(const std::shared_ptr &_message) { + app_->send(vsomeip::runtime::get()->create_response(_message)); + VSOMEIP_WARNING << "************************************************************"; + VSOMEIP_WARNING << "Shutdown method called -> going down!"; + VSOMEIP_WARNING << "************************************************************"; + std::lock_guard its_lock(mutex_); + wait_until_shutdown_method_called_ = false; + condition_.notify_one(); + } + + void on_notify_method_called(const std::shared_ptr &_message) { + (void)_message; + std::shared_ptr its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data( {0xDD}); + app_->notify(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_payload); + app_->notify(service_info_.service_id, service_info_.instance_id, + static_cast(service_info_.event_id + 1u) , its_payload); + notify_method_called_.set_value(true); + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + + if (testmode_ == pending_subscription_test::test_mode_e::REQUEST_TO_SD) { + // this testcase won't send valid subscriptions -> ensure to exit + subscription_accepted_asynchronous_ = true; + subscription_accepted_synchronous_ = true; + } + + while (!subscription_accepted_asynchronous_ || !subscription_accepted_synchronous_) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + switch (testmode_) { + case pending_subscription_test::test_mode_e::SUBSCRIBE: + async_subscription_handler_(true); + break; + case pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE: + case pending_subscription_test::test_mode_e::UNSUBSCRIBE: + case pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_NACK: + case pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_SAME_PORT: + case pending_subscription_test::test_mode_e::SUBSCRIBE_RESUBSCRIBE_MIXED: + case pending_subscription_test::test_mode_e::SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE: + case pending_subscription_test::test_mode_e::REQUEST_TO_SD: + default: + break; + } + + std::future itsFuture = notify_method_called_.get_future(); + if (std::future_status::timeout == itsFuture.wait_for(std::chrono::seconds(30))) { + ADD_FAILURE() << "notify method wasn't called within time!"; + } else { + EXPECT_TRUE(itsFuture.get()); + } + while (wait_until_shutdown_method_called_) { + condition_.wait(its_lock); + } + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + stop(); + } + + void subscription_handler_async(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, + bool _subscribed, const std::function& _cbk) { + (void)_uid; + (void)_gid; + VSOMEIP_WARNING << __func__ << " " << std::hex << _client << " subscribed." << _subscribed; + if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE) { + async_subscription_handler_ = _cbk; + static int was_called = 0; + was_called++; + EXPECT_EQ(1, was_called); + EXPECT_TRUE(_subscribed); + subscription_accepted_asynchronous_ = true; + } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE) { + static int count_subscribe = 0; + static int count_unsubscribe = 0; + _subscribed ? count_subscribe++ : count_unsubscribe++; + if (count_subscribe == 1) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + _cbk(true); + if (count_subscribe == 8 || count_unsubscribe == 7) { + subscription_accepted_asynchronous_ = true; + } + } else if (testmode_ == pending_subscription_test::test_mode_e::UNSUBSCRIBE) { + static int count_subscribe = 0; + static int count_unsubscribe = 0; + _subscribed ? count_subscribe++ : count_unsubscribe++; + if (count_subscribe == 1) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + _cbk(true); + if (count_subscribe == 2 || count_unsubscribe == 1) { + subscription_accepted_asynchronous_ = true; + } + } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_NACK) { + static int count_subscribe = 0; + static int count_unsubscribe = 0; + _subscribed ? count_subscribe++ : count_unsubscribe++; + if (count_subscribe == 1) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + if (_subscribed) { + _cbk(((count_subscribe + 1) % 2)); // nack every second subscription + } else { + _cbk(true); + } + if (count_subscribe == 8 || count_unsubscribe == 7) { + subscription_accepted_asynchronous_ = true; + } + } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_SAME_PORT) { + static int count_subscribe = 0; + static int count_unsubscribe = 0; + _subscribed ? count_subscribe++ : count_unsubscribe++; + if (count_subscribe == 1) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + _cbk(true); + if (count_subscribe == 8 || count_unsubscribe == 7) { + subscription_accepted_asynchronous_ = true; + } + } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_RESUBSCRIBE_MIXED) { + static int was_called = 0; + was_called++; + EXPECT_EQ(1, was_called); + EXPECT_TRUE(_subscribed); + _cbk(true); + subscription_accepted_asynchronous_ = true; + } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE) { + static int was_called = 0; + was_called++; + EXPECT_EQ(1, was_called); + EXPECT_TRUE(_subscribed); + subscription_accepted_asynchronous_ = true; + // this test doesn't subscribe to the second eventgroup which is handled by the asynchronous + // subscription handler, set it to true here: + subscription_accepted_synchronous_ = true; + _cbk(true); + } + } + + bool subscription_handler(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) { + (void)_subscribed; + (void)_uid; + (void)_gid; + bool ret(false); + VSOMEIP_WARNING << __func__ << " " << std::hex << _client << " subscribed. " << _subscribed; + if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE) { + static int was_called = 0; + was_called++; + EXPECT_EQ(1, was_called); + EXPECT_TRUE(_subscribed); + subscription_accepted_synchronous_ = true; + ret = true; + } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE) { + static int count_subscribed = 0; + static int count_unsubscribe = 0; + _subscribed ? count_subscribed++ : count_unsubscribe++; + if (count_subscribed == 1) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + if (count_subscribed == 8 && count_unsubscribe == 7) { + subscription_accepted_synchronous_ = true; + } + ret = true; + } else if (testmode_ == pending_subscription_test::test_mode_e::UNSUBSCRIBE) { + static int count_subscribed = 0; + static int count_unsubscribe = 0; + _subscribed ? count_subscribed++ : count_unsubscribe++; + if (count_subscribed == 1) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + if (count_subscribed == 2 && count_unsubscribe == 1) { + subscription_accepted_synchronous_ = true; + } + ret = true; + } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_NACK) { + static int count_subscribed = 0; + static int count_unsubscribe = 0; + _subscribed ? count_subscribed++ : count_unsubscribe++; + if (count_subscribed == 1) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + if (count_subscribed == 8 && count_unsubscribe == 7) { + subscription_accepted_synchronous_ = true; + } + if (_subscribed) { + ret = ((count_subscribed + 1) % 2); // nack every second subscription + } else { + ret = true; + } + } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_SAME_PORT) { + static int count_subscribed = 0; + static int count_unsubscribe = 0; + _subscribed ? count_subscribed++ : count_unsubscribe++; + + if (count_subscribed == 1) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + } + if (count_subscribed == 8 && count_unsubscribe == 7) { + subscription_accepted_synchronous_ = true; + } + ret = true; + } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_RESUBSCRIBE_MIXED) { + static int was_called = 0; + was_called++; + EXPECT_EQ(1, was_called); + EXPECT_TRUE(_subscribed); + subscription_accepted_synchronous_ = true; + ret = true; + } + return ret; + } + +private: + struct pending_subscription_test::service_info service_info_; + pending_subscription_test::test_mode_e testmode_; + std::shared_ptr app_; + + bool wait_until_registered_; + bool wait_until_shutdown_method_called_; + std::mutex mutex_; + std::condition_variable condition_; + std::atomic subscription_accepted_asynchronous_; + std::atomic subscription_accepted_synchronous_; + std::thread offer_thread_; + std::function async_subscription_handler_; + std::promise notify_method_called_; +}; + +pending_subscription_test::test_mode_e its_testmode(pending_subscription_test::test_mode_e::SUBSCRIBE); + +TEST(someip_pending_subscription_test, block_subscription_handler) +{ + pending_subscription_test_service its_sample(pending_subscription_test::service, its_testmode); +} + + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if (argc < 2) { + std::cerr << "Please pass a test mode to this binary like: " + << argv[0] << " SUBSCRIBE" << std::endl; + std::cerr << "Testmodes are [SUBSCRIBE, SUBSCRIBE_UNSUBSCRIBE, UNSUBSCRIBE, SUBSCRIBE_UNSUBSCRIBE_NACK, SUBSCRIBE_UNSUBSCRIBE_SAME_PORT]" << std::endl; + exit(1); + } + + std::string its_pased_testmode = argv[1]; + if (its_pased_testmode == std::string("SUBSCRIBE")) { + its_testmode = pending_subscription_test::test_mode_e::SUBSCRIBE; + } else if (its_pased_testmode == std::string("SUBSCRIBE_UNSUBSCRIBE")) { + its_testmode = pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE; + } else if (its_pased_testmode == std::string("UNSUBSCRIBE")) { + its_testmode = pending_subscription_test::test_mode_e::UNSUBSCRIBE; + } else if (its_pased_testmode == std::string("SUBSCRIBE_UNSUBSCRIBE_NACK")) { + its_testmode = pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_NACK; + } else if (its_pased_testmode == std::string("SUBSCRIBE_UNSUBSCRIBE_SAME_PORT")) { + its_testmode = pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_SAME_PORT; + } else if (its_pased_testmode == std::string("SUBSCRIBE_RESUBSCRIBE_MIXED")) { + its_testmode = pending_subscription_test::test_mode_e::SUBSCRIBE_RESUBSCRIBE_MIXED; + } else if (its_pased_testmode == std::string("SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE")) { + its_testmode = pending_subscription_test::test_mode_e::SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE; + } else if (its_pased_testmode == std::string("REQUEST_TO_SD")) { + its_testmode = pending_subscription_test::test_mode_e::REQUEST_TO_SD; + } + + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/readme.txt b/test/network_tests/readme.txt new file mode 100644 index 0000000..2841795 --- /dev/null +++ b/test/network_tests/readme.txt @@ -0,0 +1,573 @@ +Configuration Test +------------------ +To start the configuration test from the build directory do: + +./configuration-test -someip ../config/vsomeip-test.json + +The expected output is: + +2015-02-10 08:47:31.503874 [info] Test "HOST ADDRESS" succeeded. +2015-02-10 08:47:31.507609 [info] Test "HAS CONSOLE" succeeded. +2015-02-10 08:47:31.507865 [info] Test "HAS FILE" succeeded. +2015-02-10 08:47:31.508001 [info] Test "HAS DLT" succeeded. +2015-02-10 08:47:31.508143 [info] Test "LOGFILE" succeeded. +2015-02-10 08:47:31.508315 [info] Test "LOGLEVEL" succeeded. +2015-02-10 08:47:31.508456 [info] Test "RELIABLE_TEST_1234_0022" succeeded. +2015-02-10 08:47:31.508593 [info] Test "UNRELIABLE_TEST_1234_0022" succeeded. +2015-02-10 08:47:31.508759 [info] Test "RELIABLE_TEST_1234_0023" succeeded. +2015-02-10 08:47:31.508896 [info] Test "UNRELIABLE_TEST_1234_0023" succeeded. +2015-02-10 08:47:31.509032 [info] Test "RELIABLE_TEST_2277_0022" succeeded. +2015-02-10 08:47:31.509185 [info] Test "UNRELIABLE_TEST_2277_0022" succeeded. +2015-02-10 08:47:31.509330 [info] Test "RELIABLE_TEST_4466_0321" succeeded. +2015-02-10 08:47:31.509467 [info] Test "UNRELIABLE_TEST_4466_0321" succeeded. +2015-02-10 08:47:31.509602 [info] Test "RELIABLE_TEST_2277_0022" succeeded. +2015-02-10 08:47:31.509771 [info] Test "UNRELIABLE_TEST_2277_0022" succeeded. +2015-02-10 08:47:31.509915 [info] Test "ADDRESS_TEST_1234_0022" succeeded. +2015-02-10 08:47:31.510049 [info] Test "MIN_INITIAL_DELAY_TEST_1234_0022" succeeded. +2015-02-10 08:47:31.510354 [info] Test "MAX_INITIAL_DELAY_TEST_1234_0022" succeeded. +2015-02-10 08:47:31.510610 [info] Test "REPETITION_BASE_DELAY_TEST_1234_0022" succeeded. +2015-02-10 08:47:31.513978 [info] Test "REPETITION_MAX_TEST_1234_0022" succeeded. +2015-02-10 08:47:31.514177 [info] Test "CYCLIC_OFFER_DELAY_TEST_1234_0022" succeeded. +2015-02-10 08:47:31.514280 [info] Test "CYCLIC_REQUEST_DELAY_TEST_1234_0022" succeeded. +2015-02-10 08:47:31.514397 [info] Test "MIN_INITIAL_DELAY_TEST_1234_0023" succeeded. +2015-02-10 08:47:31.514618 [info] Test "MAX_INITIAL_DELAY_TEST_1234_0023" succeeded. +2015-02-10 08:47:31.514754 [info] Test "REPETITION_BASE_DELAY_TEST_1234_0023" succeeded. +2015-02-10 08:47:31.514901 [info] Test "REPETITION_MAX_TEST_1234_0023" succeeded. +2015-02-10 08:47:31.515052 [info] Test "CYCLIC_OFFER_DELAY_TEST_1234_0023" succeeded. +2015-02-10 08:47:31.515186 [info] Test "CYCLIC_REQUEST_DELAY_TEST_1234_0023" succeeded. +2015-02-10 08:47:31.515325 [info] Test "MIN_INITIAL_DELAY_TEST_2277_0022" succeeded. +2015-02-10 08:47:31.515395 [info] Test "MAX_INITIAL_DELAY_TEST_2277_0022" succeeded. +2015-02-10 08:47:31.515536 [info] Test "REPETITION_BASE_DELAY_TEST_2277_0022" succeeded. +2015-02-10 08:47:31.515691 [info] Test "REPETITION_MAX_TEST_2277_0022" succeeded. +2015-02-10 08:47:31.515834 [info] Test "CYCLIC_OFFER_DELAY_TEST_2277_0022" succeeded. +2015-02-10 08:47:31.515971 [info] Test "CYCLIC_REQUEST_DELAY_TEST_2277_0022" succeeded. +2015-02-10 08:47:31.516109 [info] Test "MIN_INITIAL_DELAY_TEST_2266_0022" succeeded. +2015-02-10 08:47:31.516279 [info] Test "MAX_INITIAL_DELAY_TEST_2266_0022" succeeded. +2015-02-10 08:47:31.516380 [info] Test "REPETITION_BASE_DELAY_TEST_2266_0022" succeeded. +2015-02-10 08:47:31.516512 [info] Test "REPETITION_MAX_TEST_2266_0022" succeeded. +2015-02-10 08:47:31.516610 [info] Test "CYCLIC_OFFER_DELAY_TEST_2266_0022" succeeded. +2015-02-10 08:47:31.516736 [info] Test "CYCLIC_REQUEST_DELAY_TEST_2266_0022" succeeded. +2015-02-10 08:47:31.516874 [info] Test "ADDRESS_TEST_4466_0321" succeeded. +2015-02-10 08:47:31.516974 [info] Test "SERVICE DISCOVERY PROTOCOL" succeeded. +2015-02-10 08:47:31.517106 [info] Test "SERVICE DISCOVERY PORT" succeeded. + + +Application test +---------------- + +This test tests starting and stopping a vsomeip application in various ways. + +Automatic start from build directory: + +ctest -V -R application_test + +Manual start from sub folder test of build directory: + +./application_test_starter.sh + + +Magic Cookies Test +------------------ +To run the magic cookies test you need two devices on the same network. The network addresses within +the configuration files need to be adapted to match the devices addresses. + +To start the magic-cookies-test from the build-directory do: + +Automatic start from build directory: + +ctest -V -R magic_cookies_test + +Manual start from sub folder test of build directory: + +# On external host run +./magic_cookies_test_service_start.sh + +# On local host run +./magic_cookies_test_client_start.sh + + +The expected result is an output like this on service side: + +2015-02-10 08:42:07.317695 [info] Received a message with Client/Session [1343/0001] +2015-02-10 08:42:07.360105 [error] Detected Magic Cookie within message data. Resyncing. +2015-02-10 08:42:07.360298 [info] Received a message with Client/Session [1343/0003] +2015-02-10 08:42:07.360527 [error] Detected Magic Cookie within message data. Resyncing. +2015-02-10 08:42:07.360621 [error] Detected Magic Cookie within message data. Resyncing. +2015-02-10 08:42:07.360714 [info] Received a message with Client/Session [1343/0006] +2015-02-10 08:42:07.360850 [info] Received a message with Client/Session [1343/0007] +2015-02-10 08:42:07.361021 [error] Detected Magic Cookie within message data. Resyncing. +2015-02-10 08:42:07.361107 [error] Detected Magic Cookie within message data. Resyncing. +2015-02-10 08:42:07.361191 [error] Detected Magic Cookie within message data. Resyncing. +2015-02-10 08:42:07.361276 [info] Received a message with Client/Session [1343/000b] +2015-02-10 08:42:07.361434 [info] Received a message with Client/Session [1343/000c] +2015-02-10 08:42:07.361558 [info] Received a message with Client/Session [1343/000d] +2015-02-10 08:42:07.361672 [error] Detected Magic Cookie within message data. Resyncing. +2015-02-10 08:42:07.361761 [info] Received a message with Client/Session [1343/000f] + +Header Factory Tests +-------------------- + +The following things are tested: +a) create request + --> check "Protocol Version" / "Message Type" / "Return Type" fields +b) create request, fill header, create response + --> compare header fields of request & response +c) create notification + --> check "Protocol Version" / "Message Type" / "Return Type" fields +d) create message, fill header (service/instance/method/interface version/message type) + --> send message 10 times + --> receive message and check client id / session id + +a) to c) are combined in one binary. d) is composed out of a client and service. + +To start the header factory tests from the build directory do: + +Automatic start from build directory: +ctest -V -R header_factory_test + +Manual start from build directory: +cd test +./header_factory_test +# Start client and service separately +./header_factory_test_service_start.sh & +./header_factory_test_client_start.sh +# Alternatively start client and service with one script +./header_factory_test_send_receive_starter.sh + +All tests should be marked as "passed". + +Routing Tests +------------- + +The following things are tested: +a) create a service instance + - check that it is accessible from a local client but invisible for an external client +b) create a service instance, configure it to be externally visible + - check that it is accessible from a local client and from a external client + +a) and b) are composed out of a service each and one common client binary which is used +with different configuration files. + +Automatic start from build directory: + +ctest -V -R local_routing_test + +A message will be shown when the external client should be started. + +Manual start from build directory: +cd test +# First part with local client +# Start client and service with one script +./local_routing_test_starter.sh + +# Alternatively start client and service separately +# Warning some checks are done within the *_starter.sh script. +# This should only be used for debugging +# Start the service +./local_routing_test_service_start.sh & +# Start the client +./local_routing_test_client_start.sh + +# Second part with external client +# Start client and service with one script +./external_local_routing_test_starter.sh +# Start the external client from an external host when the message is displayed to start it +./external_local_routing_test_client_external_start.sh + +# Alternatively start client and service separately +# Warning some checks are done within the *_starter.sh script. +# This should only be used for debugging +# Start the service +./external_local_routing_test_service_start.sh & +# Start the client +./local_routing_test_client_start.sh +# Start the external client from an external host after local client has finished +./external_local_routing_test_client_external_start.sh + + +All tests should be marked as "passed". + +Payload Tests +------------- + +The following things are tested: +a) create a local service + - send messages with payloads of different size from a local client to the service + - check that the messages are received correctly + - measure the throughput +b) create a service instance, configure it to be externally visible + - send messages with payloads of different size from a local client to the service + - check that the messages are received correctly + - measure the throughput +c) create a service instance, configure it to be externally visible + - send messages with payloads of different size from an external client to the service + - check that the messages are received correctly + - measure the throughput +d) create a service instance, configure it to be externally visible + - send messages with payloads of different size from a local client to the service + - send messages with payloads of different size from an external client to the service + - check that the messages are received correctly + - measure the throughput + +The tests a) to d) are composed out of a service and a client binary which are called +with different configuration files and parameters. + +Automatic start from build directory: + +ctest -V -R payload_test + +A message will be shown when the external clients should be started. + +Manual start from build directory: +cd test + +# First part with local client +# start client and service with one script +./local_payload_test_starter.sh + +# Alternatively start client and service separately +# Warning some checks are done within the *_starter.sh script. +# This should only be used for debugging +./local_payload_test_service_start.sh & +./local_payload_test_client_start.sh + +# Second part with external visible service and local client +# start client and service with one script +./external_local_payload_test_client_local_starter.sh + +# Alternatively start client and service separately +# Warning some checks are done within the *_starter.sh script. +# This should only be used for debugging +./external_local_payload_test_service_start.sh & +./external_local_payload_test_client_local_start.sh + +# Third part with external visible service and external client +# start client and service with one script +./external_local_payload_test_client_external_starter.sh +# Start the external client from an external host if asked to +./external_local_payload_test_client_external_start.sh + +# Alternatively start client and service separately +# Warning some checks are done within the *_starter.sh script. +# This should only be used for debugging +./external_local_payload_test_service_client_external_start.sh +# Start the external client from an external host +./external_local_payload_test_client_external_start.sh + +# Fourth part with external visible service and local and external client +# start client and service with one script +./external_local_payload_test_client_local_and_external_starter.sh +# Start the external client from an external host if asked to +./external_local_payload_test_client_external_start.sh + +# Alternatively start client and service separately +# Warning some checks are done within the *_starter.sh script. +# This should only be used for debugging +./external_local_payload_test_service_client_external_start.sh & +# Start the local client +VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_local \ +VSOMEIP_CONFIGURATION=external_local_payload_test_client_local.json \ +./payload_test_client --dont-shutdown-service +# Start the external client after the local client is finished from an +# external host +./external_local_payload_test_client_external_start.sh + +All tests should be marked as "passed". + + +Big payload tests +----------------- + +This test tests the possibility to sent messages with bigger payloads +for local and TCP communication. + +The test will send a messages with 600k payload from a client to a service. +The service will reply with a response containing 600k payload as well. +This is repeated 10 times. +There is a version for local and for TCP communication available. +Additionally there are test versions available which sent up to 10MiB big +messages and a version which tests the limitiation of message sizes configurable +via json file. + +Automatic start from the build directory: + +ctest -V -R big_payload_test_local + +Manual start from sub folder test of build directory: + +./big_payload_test_service_local_start.sh & +./big_payload_test_client_local_start.sh + + +Automatic start of the TCP version from the build directory: + +ctest -V -R big_payload_test_external + +Manual start from sub folder test of build directory: + +./big_payload_test_client_start.sh + +# On external host run +./big_payload_test_service_external_start.sh + + +Client ID tests +--------------- + +This tests tests communication over two nodes with multiple services on both +nodes. + +The test setup is as followed: +* There are six services with one method each. +* Three of the services run on node 1. +* Three of the services run on node 2. +* Each of the services sends ten requests to the other services and waits + until it received a response for every request. +* If all responses have been received, the service shutdown. + +Automatic start from the build directory: + +ctest -V -R client_id_test_diff_client_ids_diff_ports + +Manual start from sub folder test of build directory: + +./client_id_test_master_starter.sh client_id_test_diff_client_ids_diff_ports_master.json + +Second version where all services on one node use the same port: + +Automatic start from the build directory: + +ctest -V -R client_id_test_diff_client_ids_same_ports + +Manual start from sub folder test of build directory: + +./client_id_test_master_starter.sh client_id_test_diff_client_ids_same_ports_master.json + + +Subscribe notify tests +---------------------- +This tests tests subscribe notify mechanism over two nodes with multiple services +on both nodes. + +The test setup is as followed: +* There are six services offering one event each. +* Three of the services run on node 1. +* Three of the services run on node 2. +* Each of the services waits until all other services are available. +* Each of the services subscribes to the offered event of all the other services. +* Each of the services then waits until the other services have subscribed to + its event. +* Each of the services then starts to sent out ten notifications for its event. +* Each service waits until it received the correct amount of notifications from + all other services. +* If all notifications have been received, the service shuts down. + +Automatic start from the build directory (example): + +ctest -V -R subscribe_notify_test_diff_client_ids_diff_ports_udp + +Manual start from sub folder test of build directory: + +./subscribe_notify_test_master_starter.sh UDP subscribe_notify_test_diff_client_ids_diff_ports_master.json + +There are multiple versions of this test which differ in the used subscription +method and port setup (use ctest -N to see all). For manual start the desired +description method has to be passed to the starter script as first parameter. + +The subscribe_notify_test_one_event_two_eventgroups_* tests are testing the +requirement that for events which are member of multiple eventgroups initial +events shall be sent per eventgroup. However normal updates of the event should +be sent only once even if a remote subscriber is subscribed to multiple of the +event's eventgroups (TR_SOMEIP_00570). + + +CPU load test +------------- +This test does a increasing number of synchronous function calls to the same +method of the service and measures CPU load for each batch of function calls. +All method calls transport a payload of 40 Bytes. The responses don't transport +any payload. + +The CPU load is measured thorugh the proc fs. +If the test prints a message like: + + Synchronously sent 0890 messages. CPU load [%]: 12.68 + +This means that the test process consumed 12% of the jiffies consumed by +complete system while doing 890 methodcalls. + +Automatic start from the build directory (example): + +ctest -V -R cpu_load_test + + +Initial event tests +---------------------- +This tests tests initial event mechanism over two nodes with multiple services +on both nodes. + +The test setup is as followed: +* There are six services offering one event each. +* Three of the services run on node 1. +* Three of the services run on node 2. +* All of the services initially set their event to their service id and notify + once +* On each node there are 20 client applications which subscribe to all of the + services events which are started at different times +* Each client waits until it received one notification (the initial one) from + all services and then exits. +* If all clients exited, the services are killed as well + +Automatic start from the build directory (example): + +ctest -V -R initial_event_test_diff_client_ids_diff_ports_udp + +Manual start from sub folder test of build directory: +./initial_event_test_master_starter.sh UDP initial_event_test_diff_client_ids_diff_ports_master.json + +There are multiple versions of this test which differ in the used subscription +method and port setup (use ctest -N to see all). For manual start the desired +description method has to be passed to the starter script as first parameter. + +Offer tests +----------- +This tests test various cases of offering a service and error recovery +after an application became unresponsive + +* Rejecting offer of service instance whose hosting application is + still alive. +* Rejecting offer of service instance whose hosting application is + still alive with daemon +* Accepting offer of service instance whose hosting application + crashed with (send SIGKILL) +* Accepting offer of service instance whose hosting application became + unresponsive (SIGSTOP) +* Rejecting offers for which there is already a pending offer +* Rejecting remote offer for which there is already a local offer +* Rejecting a local offer for which there is already a remote offer + +Automatic start from the build directory (example): + +ctest -V -R offer_tests + +Manual start from sub folder test of build directory: +./offer_test_local_starter +./offer_test_external_master_starter.sh + +Tests in detail: +Rejecting offer of service instance whose hosting application is still +alive: +* start application which offers service +* start client which continuously exchanges messages with the service +* start application which offers the same service again -> should be + rejected and an error message should be printed. +* Message exchange with client application should not be interrupted. + +Rejecting offer of service instance whose hosting application is still +alive with daemon +* start daemon (needed as he has to ping the offering client) +* start application which offers service +* start client which continuously exchanges messages with the service +* start application which offers the same service again -> should be + rejected and an error message should be printed. +* Message exchange with client application should not be interrupted. + +Accepting offer of service instance whose hosting application crashed +with (send SIGKILL) +* start daemon +* start application which offers service +* start client which exchanges messages with the service +* kill application with SIGKILL +* start application which offers the same service again -> should be + accepted. +* start another client which exchanges messages with the service +* Client should now communicate with new offerer. + +Accepting offer of service instance whose hosting application became +unresponsive (SIGSTOP) +* start daemon +* start application which offers service +* Send a SIGSTOP to the service to make it unresponsive +* start application which offers the same service again -> should be + marked as PENDING_OFFER and a ping should be sent to the paused + application. +* After the timeout passed the new offer should be accepted. +* start client which exchanges messages with the service +* Client should now communicate with new offerer. + +Rejecting offers for which there is already a pending offer +* start daemon +* start application which offers service +* Send a SIGSTOP to the service to make it unresponsive +* start application which offers the same service again -> should be + marked as PENDING_OFFER and a ping should be sent to the paused + application. +* start application which offers the same service again -> should be + rejected as there is already a PENDING_OFFER pending. +* After the timeout passed the new offer should be accepted. +* start client which exchanges messages with the service +* Client should now communicate with new offerer. + +Rejecting a local offer for which there is already a remote offer: +* start daemon +* start application which offers service +* start daemon remotely +* start same application which offers the same service again remotely + -> should be rejected as there is already a service instance + running in the network + +Rejecting remote offer for which there is already a local offer +* start application which offers service +* send SD message trying to offer the same service instance as already + offered locally from a remote host -> should be rejected + +nPDU tests +----------------- + +This test is intended to test the functionality of the so called nPDU +feature. The test setup is as followed: + +* There are two nodes, one hosting the services, one hosting the clients. +* On each of the nodes is a routing manager daemon (RMD) started whose only + purpose is to provide routing manager functionality and shutdown the clients + and services at the end. +* There are four services created. Each of the services has four methods. +* All services are listening on the same port. Therefore there only is: + * one server endpoint created in the RMD on service side + * one client endpoint created in the RMD on client side +* There are four clients created. Each of the clients will: + * Create a thread for each service + * Create a thread for each method of each service + * Send multiple messages with increasing payload to each of the services' + methods from the corresponding thread. + * After sending the threads will sleep the correct amount of time to insure + applicative debounce > debounce time + max retention time. +* After all messages have been sent to the services the clients will notify the + RMD that they're finished. The RMD then instructs the RMD on service side to + shutdown the services and exit afterwards. After that the RMD on client side + exits as well. +* Upon receiving a method call the service will check if the debounce time + specified in the json file for this method was undershot and print out a + warning. +* The test first runs in synchronous mode and waits for a response of the + service before sending the next message. +* After that the test runs in a mode where no response from the service are + required (message type REQUEST_NO_RETURN) thus the clients send at maximum + allowed frequency. + +Automatic start from build directory: + +ctest -V -R npdu_test_UDP +ctest -V -R npdu_test_TCP + +A message will be shown when the external clients should be started. + +Manual start: +# Service side +./npdu_test_service_npdu_start.sh + +# Client side UDP mode +./npdu_test_client_npdu_start.sh UDP + +# Client side TCP mode +./npdu_test_client_npdu_start.sh TCP diff --git a/test/network_tests/restart_routing_tests/restart_routing_test_autoconfig.json b/test/network_tests/restart_routing_tests/restart_routing_test_autoconfig.json new file mode 100644 index 0000000..f50dba7 --- /dev/null +++ b/test/network_tests/restart_routing_tests/restart_routing_test_autoconfig.json @@ -0,0 +1,24 @@ +{ + "unicast" : "127.0.0.1", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "warning", + "console" : "true", + "file" : + { + "enable" : "true", + "path" : "/var/log/vsomeip.log" + }, + + "dlt" : "true" + }, + + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30491", + "protocol" : "udp" + } +} diff --git a/test/network_tests/restart_routing_tests/restart_routing_test_client.cpp b/test/network_tests/restart_routing_tests/restart_routing_test_client.cpp new file mode 100644 index 0000000..847594e --- /dev/null +++ b/test/network_tests/restart_routing_tests/restart_routing_test_client.cpp @@ -0,0 +1,163 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "restart_routing_test_client.hpp" + +routing_restart_test_client::routing_restart_test_client() + : app_(vsomeip::runtime::get()->create_application()), + is_available_(false), + sender_(std::bind(&routing_restart_test_client::run, this)), + received_responses_(0) { + +} + +bool routing_restart_test_client::init() { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + + app_->register_state_handler( + std::bind(&routing_restart_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, + std::bind(&routing_restart_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&routing_restart_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + return true; +} + +void routing_restart_test_client::start() { + VSOMEIP_INFO << "Starting..."; + + app_->start(); +} + +void routing_restart_test_client::stop() { + VSOMEIP_INFO << "Stopping..."; + + shutdown_service(); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + app_->clear_all_handler(); + app_->stop(); +} + +void routing_restart_test_client::on_state(vsomeip::state_type_e _state) { + if(_state == vsomeip::state_type_e::ST_REGISTERED) { + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); + } +} + +void routing_restart_test_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + + VSOMEIP_INFO << std::hex << "Client 0x" << app_->get_client() + << " : Service [" << std::setw(4) << std::setfill('0') << std::hex + << _service << "." << _instance << "] is " + << (_is_available ? "available." : "NOT available."); + + if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service + && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) { + std::unique_lock its_lock(mutex_); + if(is_available_ && !_is_available) { + is_available_ = false; + } + else if(_is_available && !is_available_) { + is_available_ = true; + condition_.notify_one(); + } + } +} + +void routing_restart_test_client::on_message(const std::shared_ptr &_response) { + VSOMEIP_INFO << "Received a response from Service [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() + << "." + << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() + << "] to Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() + << "/" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() + << "]"; + + if (_response->get_service() == vsomeip_test::TEST_SERVICE_SERVICE_ID && + _response->get_instance() == vsomeip_test::TEST_SERVICE_INSTANCE_ID) { + received_responses_++; + if (received_responses_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS) { + VSOMEIP_WARNING << std::hex << app_->get_client() + << ": Received all messages ~> going down!"; + all_responses_received_.set_value(); + } + } +} + +void routing_restart_test_client::run() { + for (uint32_t i = 0; i < vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS; ++i) { + { + std::unique_lock its_lock(mutex_); + while (!is_available_) + { + condition_.wait(its_lock); + } + } + + auto request = vsomeip::runtime::get()->create_request(false); + request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); + app_->send(request); + + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + } + + if (std::future_status::ready == all_responses_received_.get_future().wait_for(std::chrono::milliseconds(10000))) { + EXPECT_EQ(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS, + received_responses_); + VSOMEIP_WARNING << "Received all answers"; + } else { + ADD_FAILURE() << "Didn't receive all responses within time"; + } + + stop(); +} + +void routing_restart_test_client::join_sender_thread() +{ + if (sender_.joinable()) { + sender_.join(); + } +} + +void routing_restart_test_client::shutdown_service() { + auto request = vsomeip::runtime::get()->create_request(false); + request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); + app_->send(request); +} + +TEST(someip_restart_routing_test, request_response_over_restart) +{ + routing_restart_test_client test_client; + if (test_client.init()) { + test_client.start(); + test_client.join_sender_thread(); + } +} + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/restart_routing_tests/restart_routing_test_client.hpp b/test/network_tests/restart_routing_tests/restart_routing_test_client.hpp new file mode 100644 index 0000000..cd4a12f --- /dev/null +++ b/test/network_tests/restart_routing_tests/restart_routing_test_client.hpp @@ -0,0 +1,52 @@ + +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef RESTART_ROUTING_TEST_CLIENT_HPP +#define RESTART_ROUTING_TEST_CLIENT_HPP + +#include + +#include + +#include "../someip_test_globals.hpp" + +#include +#include +#include +#include +#include + +class routing_restart_test_client { +public: + routing_restart_test_client(); + bool init(); + void start(); + void stop(); + + void on_state(vsomeip::state_type_e _state); + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available); + void on_message(const std::shared_ptr &_response); + + void run(); + void join_sender_thread(); + +private: + void shutdown_service(); + + std::shared_ptr app_; + + std::mutex mutex_; + std::condition_variable condition_; + bool is_available_; + + std::thread sender_; + + std::atomic received_responses_; + std::promise all_responses_received_; +}; + +#endif // RESTART_ROUTING_TEST_CLIENT_HPP diff --git a/test/network_tests/restart_routing_tests/restart_routing_test_client.json b/test/network_tests/restart_routing_tests/restart_routing_test_client.json new file mode 100644 index 0000000..93fafab --- /dev/null +++ b/test/network_tests/restart_routing_tests/restart_routing_test_client.json @@ -0,0 +1,48 @@ +{ + "unicast" : "127.0.0.1", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "warning", + "console" : "true", + "file" : + { + "enable" : "true", + "path" : "/var/log/vsomeip.log" + }, + + "dlt" : "true" + }, + + "applications" : + [ + { + "name" : "restart_routing_test_client1", + "id" : "0x1343" + }, + { + "name" : "restart_routing_test_client2", + "id" : "0x1344" + }, + { + "name" : "restart_routing_test_client3", + "id" : "0x1345" + }, + { + "name" : "restart_routing_test_client4", + "id" : "0x1346" + } + ], + "services" : + [ + ], + + "routing" : "routingmanagerd", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30491", + "protocol" : "udp" + } +} diff --git a/test/network_tests/restart_routing_tests/restart_routing_test_client_start.sh b/test/network_tests/restart_routing_tests/restart_routing_test_client_start.sh new file mode 100755 index 0000000..de944b9 --- /dev/null +++ b/test/network_tests/restart_routing_tests/restart_routing_test_client_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client +export VSOMEIP_CONFIGURATION=restart_routing_test_client.json +./restart_routing_test_client diff --git a/test/network_tests/restart_routing_tests/restart_routing_test_service.cpp b/test/network_tests/restart_routing_tests/restart_routing_test_service.cpp new file mode 100644 index 0000000..67621cd --- /dev/null +++ b/test/network_tests/restart_routing_tests/restart_routing_test_service.cpp @@ -0,0 +1,133 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "restart_routing_test_service.hpp" + +routing_restart_test_service::routing_restart_test_service() : + app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + blocked_(false), + number_of_received_messages_(0), + offer_thread_(std::bind(&routing_restart_test_service::run, this)) { +} + +bool routing_restart_test_service::init() { + std::lock_guard its_lock(mutex_); + + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, + std::bind(&routing_restart_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, + std::bind(&routing_restart_test_service::on_message_shutdown, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&routing_restart_test_service::on_state, this, + std::placeholders::_1)); + return true; +} + +void routing_restart_test_service::start() { + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void routing_restart_test_service::stop() { + VSOMEIP_INFO << "Stopping..."; + app_->clear_all_handler(); + app_->stop(); +} + +void routing_restart_test_service::join_offer_thread() { + if (offer_thread_.joinable()) { + offer_thread_.join(); + } +} + +void routing_restart_test_service::offer() { + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void routing_restart_test_service::stop_offer() { + app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void routing_restart_test_service::on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : + "deregistered."); + + if(_state == vsomeip::state_type_e::ST_REGISTERED) { + if(!is_registered_) { + is_registered_ = true; + std::lock_guard its_lock(mutex_); + blocked_ = true; + // "start" the run method thread + condition_.notify_one(); + } + } + else { + is_registered_ = false; + } +} + +void routing_restart_test_service::on_message(const std::shared_ptr& _request) { + ASSERT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _request->get_service()); + ASSERT_EQ(vsomeip_test::TEST_SERVICE_METHOD_ID, _request->get_method()); + + VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _request->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _request->get_session() << "]"; + + // send response + std::shared_ptr its_response = + vsomeip::runtime::get()->create_response(_request); + + app_->send(its_response); + + number_of_received_messages_++; + if(number_of_received_messages_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS) { + VSOMEIP_INFO << "Received all messages!"; + } +} + +void routing_restart_test_service::on_message_shutdown( + const std::shared_ptr& _request) { + (void)_request; + VSOMEIP_INFO << "Shutdown method was called, going down now."; + stop(); +} + +void routing_restart_test_service::run() { + std::unique_lock its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); + + offer(); +} + +TEST(someip_restart_routing_test, send_response_for_every_request) { + routing_restart_test_service test_service; + if (test_service.init()) { + test_service.start(); + test_service.join_offer_thread(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/restart_routing_tests/restart_routing_test_service.hpp b/test/network_tests/restart_routing_tests/restart_routing_test_service.hpp new file mode 100644 index 0000000..3abfe17 --- /dev/null +++ b/test/network_tests/restart_routing_tests/restart_routing_test_service.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef RESTART_ROUTING_TEST_SERVICE_HPP +#define RESTART_ROUTING_TEST_SERVICE_HPP + +#include + +#include + +#include "../someip_test_globals.hpp" + +#include +#include +#include + +class routing_restart_test_service { +public: + routing_restart_test_service(); + bool init(); + void start(); + void stop(); + void offer(); + void stop_offer(); + void join_offer_thread(); + void on_state(vsomeip::state_type_e _state); + void on_message(const std::shared_ptr &_request); + void on_message_shutdown(const std::shared_ptr &_request); + void run(); + +private: + std::shared_ptr app_; + bool is_registered_; + + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + std::uint32_t number_of_received_messages_; + std::thread offer_thread_; +}; + +#endif // RESTART_ROUTING_TEST_SERVICE_HPP diff --git a/test/network_tests/restart_routing_tests/restart_routing_test_service.json b/test/network_tests/restart_routing_tests/restart_routing_test_service.json new file mode 100644 index 0000000..9a1d3bf --- /dev/null +++ b/test/network_tests/restart_routing_tests/restart_routing_test_service.json @@ -0,0 +1,44 @@ +{ + "unicast" : "127.0.0.1", + "logging" : + { + "level" : "warning", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/tmp/vsomeip.log" + }, + + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "routingmanagerd", + "id" : "0x0815" + }, + { + "name" : "restart_routing_test_service", + "id" : "0x1277" + } + ], + + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678" + } + ], + + "routing" : "routingmanagerd", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp" + } +} diff --git a/test/network_tests/restart_routing_tests/restart_routing_test_service_start.sh b/test/network_tests/restart_routing_tests/restart_routing_test_service_start.sh new file mode 100755 index 0000000..b82be7c --- /dev/null +++ b/test/network_tests/restart_routing_tests/restart_routing_test_service_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=restart_routing_test_service +export VSOMEIP_CONFIGURATION=restart_routing_test_service.json +./restart_routing_test_service diff --git a/test/network_tests/restart_routing_tests/restart_routing_test_starter.sh b/test/network_tests/restart_routing_tests/restart_routing_test_starter.sh new file mode 100755 index 0000000..cffd14c --- /dev/null +++ b/test/network_tests/restart_routing_tests/restart_routing_test_starter.sh @@ -0,0 +1,312 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit sucessfully. + +FAIL=0 + +# NOW WITHOUT JSON +echo "----------------------------------------------" +echo "----------------------------------------------" +echo " Run test with auto configuration " +echo "----------------------------------------------" +echo "----------------------------------------------" + +export VSOMEIP_CONFIGURATION=restart_routing_test_autoconfig.json + +../../examples/routingmanagerd/./routingmanagerd & +DAEMON_PID=$! + +sleep 2 + +# Start the service +export VSOMEIP_APPLICATION_NAME=restart_routing_test_service +./restart_routing_test_service & +SERIVCE_PID=$! + +# Start the client1 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client1 +./restart_routing_test_client & +CLIENT1_PID=$! + +# Start the client2 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client2 +./restart_routing_test_client & +CLIENT2_PID=$! + +# Start the client3 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client3 +./restart_routing_test_client & +CLIENT3_PID=$! + +# Start the client4 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client4 +./restart_routing_test_client & +CLIENT4_PID=$! + +sleep 2 +echo "----------------------------------------------" +echo " let routingmanagerd crash (kill -9) " +echo "----------------------------------------------" +kill -9 $DAEMON_PID +echo "----------------------------------------------" +echo " restart routingmanagerd " +echo "----------------------------------------------" +sleep 2 + +../../examples/routingmanagerd/./routingmanagerd & +DAEMON_PID=$! + +wait $SERIVCE_PID || ((FAIL+=1)) +wait $CLIENT1_PID || ((FAIL+=1)) +wait $CLIENT2_PID || ((FAIL+=1)) +wait $CLIENT3_PID || ((FAIL+=1)) +wait $CLIENT4_PID || ((FAIL+=1)) + +kill $DAEMON_PID +wait $DAEMON_PID + +# Check if client and server both exited sucessfully and the service didnt't +# have any open tcp/udp sockets +if [ $FAIL -eq 0 ] +then + echo "Test Succeeded" +else + exit 1 +fi + +# NOW WITHOUT VSOMEIPD +echo "----------------------------------------------" +echo "----------------------------------------------" +echo " Run test with auto configuration no deamon " +echo "----------------------------------------------" +echo "----------------------------------------------" + +sleep 2 + +# Start the service +export VSOMEIP_APPLICATION_NAME=restart_routing_test_service +./restart_routing_test_service & +SERIVCE_PID=$! + +# Start the client1 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client1 +./restart_routing_test_client & +CLIENT1_PID=$! + +# Start the client2 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client2 +./restart_routing_test_client & +CLIENT2_PID=$! + +# Start the client3 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client3 +./restart_routing_test_client & +CLIENT3_PID=$! + +# Start the client4 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client4 +./restart_routing_test_client & +CLIENT4_PID=$! + +sleep 2 +echo "----------------------------------------------" +echo " let service (routing) crash (kill -9) " +echo "----------------------------------------------" +kill -9 $SERIVCE_PID +echo "----------------------------------------------" +echo " restart service (routing) " +echo "----------------------------------------------" +sleep 2 + +# Start the service +export VSOMEIP_APPLICATION_NAME=restart_routing_test_service +./restart_routing_test_service & +SERIVCE_PID=$! + +wait $SERIVCE_PID || ((FAIL+=1)) +wait $CLIENT1_PID || ((FAIL+=1)) +wait $CLIENT2_PID || ((FAIL+=1)) +wait $CLIENT3_PID || ((FAIL+=1)) +wait $CLIENT4_PID || ((FAIL+=1)) + +# Check if client and server both exited sucessfully and the service didnt't +# have any open tcp/udp sockets +if [ $FAIL -eq 0 ] +then + echo "Test Succeeded" +else + exit 1 +fi + + +echo "----------------------------------------------" +echo "----------------------------------------------" +echo " Run test with json configuration " +echo "----------------------------------------------" +echo "----------------------------------------------" + +sleep 2 + +export VSOMEIP_CONFIGURATION=restart_routing_test_service.json +../../examples/routingmanagerd/./routingmanagerd & +DAEMON_PID=$! + +# Start the service +export VSOMEIP_APPLICATION_NAME=restart_routing_test_service +export VSOMEIP_CONFIGURATION=restart_routing_test_service.json +./restart_routing_test_service & +SERIVCE_PID=$! + +# Start the client1 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client1 +export VSOMEIP_CONFIGURATION=restart_routing_test_client.json +./restart_routing_test_client & +CLIENT1_PID=$! + +# Start the client2 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client2 +export VSOMEIP_CONFIGURATION=restart_routing_test_client.json +./restart_routing_test_client & +CLIENT2_PID=$! + +# Start the client3 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client3 +export VSOMEIP_CONFIGURATION=restart_routing_test_client.json +./restart_routing_test_client & +CLIENT3_PID=$! + +# Start the client4 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client4 +export VSOMEIP_CONFIGURATION=restart_routing_test_client.json +./restart_routing_test_client & +CLIENT4_PID=$! + +sleep 2 +echo "----------------------------------------------" +echo " let routingmanagerd crash (kill -9) " +echo "----------------------------------------------" +kill -9 $DAEMON_PID +echo "----------------------------------------------" +echo " restart routingmanagerd " +echo "----------------------------------------------" +sleep 2 + +export VSOMEIP_CONFIGURATION=restart_routing_test_service.json +../../examples/routingmanagerd/./routingmanagerd & +DAEMON_PID=$! + +wait $SERIVCE_PID || ((FAIL+=1)) +wait $CLIENT1_PID || ((FAIL+=1)) +wait $CLIENT2_PID || ((FAIL+=1)) +wait $CLIENT3_PID || ((FAIL+=1)) +wait $CLIENT4_PID || ((FAIL+=1)) + +kill $DAEMON_PID +wait $DAEMON_PID + +# Check if client and server both exited sucessfully and the service didnt't +# have any open tcp/udp sockets +if [ $FAIL -eq 0 ] +then + echo "Test Succeeded" +else + exit 1 +fi + +echo "----------------------------------------------" +echo "----------------------------------------------" +echo "Run test with json configuration + kill service" +echo "----------------------------------------------" +echo "----------------------------------------------" + +sleep 2 + +export VSOMEIP_CONFIGURATION=restart_routing_test_service.json +../../examples/routingmanagerd/./routingmanagerd & +DAEMON_PID=$! + +# Start the service +export VSOMEIP_APPLICATION_NAME=restart_routing_test_service +export VSOMEIP_CONFIGURATION=restart_routing_test_service.json +./restart_routing_test_service & +SERIVCE_PID=$! + +# Start the client1 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client1 +export VSOMEIP_CONFIGURATION=restart_routing_test_client.json +./restart_routing_test_client & +CLIENT1_PID=$! + +# Start the client2 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client2 +export VSOMEIP_CONFIGURATION=restart_routing_test_client.json +./restart_routing_test_client & +CLIENT2_PID=$! + +# Start the client3 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client3 +export VSOMEIP_CONFIGURATION=restart_routing_test_client.json +./restart_routing_test_client & +CLIENT3_PID=$! + +# Start the client4 +export VSOMEIP_APPLICATION_NAME=restart_routing_test_client4 +export VSOMEIP_CONFIGURATION=restart_routing_test_client.json +./restart_routing_test_client & +CLIENT4_PID=$! + +sleep 2 +echo "----------------------------------------------" +echo " let routingmanagerd crash (kill -9) " +echo "----------------------------------------------" +kill -9 $DAEMON_PID +sleep 1 +echo "----------------------------------------------" +echo " let service crash (kill -9) " +echo "----------------------------------------------" +kill -9 $SERIVCE_PID +echo "----------------------------------------------" +echo " restart routingmanagerd " +echo "----------------------------------------------" +sleep 2 + +export VSOMEIP_CONFIGURATION=restart_routing_test_service.json +../../examples/routingmanagerd/./routingmanagerd & +DAEMON_PID=$! + +echo "----------------------------------------------" +echo " restart service " +echo "----------------------------------------------" +sleep 1 + +# Start the service again +export VSOMEIP_APPLICATION_NAME=restart_routing_test_service +export VSOMEIP_CONFIGURATION=restart_routing_test_service.json +./restart_routing_test_service & +SERIVCE_PID=$! + +wait $SERIVCE_PID || ((FAIL+=1)) +wait $CLIENT1_PID || ((FAIL+=1)) +wait $CLIENT2_PID || ((FAIL+=1)) +wait $CLIENT3_PID || ((FAIL+=1)) +wait $CLIENT4_PID || ((FAIL+=1)) + +kill $DAEMON_PID +wait $DAEMON_PID + +# Check if client and server both exited sucessfully and the service didnt't +# have any open tcp/udp sockets +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/routing_tests/conf/external_local_routing_test_client_external.json.in b/test/network_tests/routing_tests/conf/external_local_routing_test_client_external.json.in new file mode 100644 index 0000000..0aaa664 --- /dev/null +++ b/test/network_tests/routing_tests/conf/external_local_routing_test_client_external.json.in @@ -0,0 +1,47 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "netmask" : "255.255.255.0", + "diagnosis" : "0x16", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "true", + "path" : "/var/log/vsomeip.log" + }, + + "dlt" : "true" + }, + + "applications" : + [ + { + "name" : "external_local_routing_test_client_external", + "id" : "0x1644" + } + ], + + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + } + ], + + "routing": { + "enabled": false, + "host": "external_local_routing_test_client_external" + }, + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30491", + "protocol" : "udp" + } +} diff --git a/test/network_tests/routing_tests/conf/external_local_routing_test_service.json.in b/test/network_tests/routing_tests/conf/external_local_routing_test_service.json.in new file mode 100644 index 0000000..a4deb82 --- /dev/null +++ b/test/network_tests/routing_tests/conf/external_local_routing_test_service.json.in @@ -0,0 +1,42 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "diagnosis":"0x12", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/tmp/vsomeip.log" + }, + + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "external_local_routing_test_service", + "id" : "0x1277" + } + ], + + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unreliable" : "30509" + } + ], + + "routing" : "external_local_routing_test_service", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp" + } +} diff --git a/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.bat.in b/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.bat.in new file mode 100755 index 0000000..d7abe64 --- /dev/null +++ b/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.bat.in @@ -0,0 +1,79 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit sucessfully. + +FAIL=0 + +# Parameter 1: the pid to check +check_tcp_udp_sockets_are_closed () +{ + # Check that the service does not listen on any TCP/UDP socket + # or has any active connection via a TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] + then + ((FAIL+=1)) + fi + + SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] + then + ((FAIL+=1)) + fi +} + +# Start the service +export VSOMEIP_APPLICATION_NAME=local_routing_test_service +if [ "$VSOMEIP_CONFIGURATION_SERVICE" != "" ] +then + export VSOMEIP_CONFIGURATION=$VSOMEIP_CONFIGURATION_SERVICE +else + export VSOMEIP_CONFIGURATION=local_routing_test_service.json +fi +./local_routing_test_service & +SERIVCE_PID=$! +sleep 1; + +check_tcp_udp_sockets_are_closed $SERIVCE_PID + +# Start the client +export VSOMEIP_APPLICATION_NAME=local_routing_test_client +if [ "$VSOMEIP_CONFIGURATION_CLIENT" != "" ] +then + export VSOMEIP_CONFIGURATION=$VSOMEIP_CONFIGURATION_CLIENT +else + export VSOMEIP_CONFIGURATION=local_routing_test_client.json +fi +./local_routing_test_client & +CLIENT_PID=$! + +check_tcp_udp_sockets_are_closed $SERIVCE_PID +check_tcp_udp_sockets_are_closed $CLIENT_PID + +# Wait until client and service are finished +for job in $(jobs -p) +do + # Fail gets incremented if either client or service exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +# Check if client and server both exited successfully and the service didnt't +# have any open +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.in b/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.in new file mode 100755 index 0000000..d5b83f4 --- /dev/null +++ b/test/network_tests/routing_tests/conf/local_routing_test_starter.sh.in @@ -0,0 +1,79 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit sucessfully. + +FAIL=0 + +# Parameter 1: the pid to check +check_tcp_udp_sockets_are_closed () +{ + # Check that the service does not listen on any TCP/UDP socket + # or has any active connection via a TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] + then + ((FAIL+=1)) + fi + + SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] + then + ((FAIL+=1)) + fi +} + +export VSOMEIP_CONFIGURATION=local_routing_test_service.json +# start daemon +../../examples/routingmanagerd/./routingmanagerd & +PID_VSOMEIPD=$! + +WAIT_PIDS=() +# Start the service +export VSOMEIP_APPLICATION_NAME=local_routing_test_service +./local_routing_test_service & +SERIVCE_PID=$! +WAIT_PIDS+=($!) +sleep 1; + +check_tcp_udp_sockets_are_closed $SERIVCE_PID + +# Start the client +export VSOMEIP_APPLICATION_NAME=local_routing_test_client +export VSOMEIP_CONFIGURATION=local_routing_test_client.json +./local_routing_test_client & +CLIENT_PID=$! +WAIT_PIDS+=($!) + +check_tcp_udp_sockets_are_closed $SERIVCE_PID +check_tcp_udp_sockets_are_closed $CLIENT_PID + +# Wait until client and service are finished +for job in ${WAIT_PIDS[*]} +do + # Fail gets incremented if either client or service exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +kill $PID_VSOMEIPD +sleep 1 + +# Check if client and server both exited successfully and the service didnt't +# have any open +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/routing_tests/external_local_routing_test_client_external_start.sh b/test/network_tests/routing_tests/external_local_routing_test_client_external_start.sh new file mode 100755 index 0000000..098c777 --- /dev/null +++ b/test/network_tests/routing_tests/external_local_routing_test_client_external_start.sh @@ -0,0 +1,17 @@ +#!/bin/bash -ex +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=external_local_routing_test_client_external +export VSOMEIP_CONFIGURATION=external_local_routing_test_client_external.json +./local_routing_test_client & +client=$! + +for _ in {1..100} +do + find /tmp -ls + lsof -nw -p "$client" || continue +done +wait "$client" diff --git a/test/network_tests/routing_tests/external_local_routing_test_service.cpp b/test/network_tests/routing_tests/external_local_routing_test_service.cpp new file mode 100644 index 0000000..46b8138 --- /dev/null +++ b/test/network_tests/routing_tests/external_local_routing_test_service.cpp @@ -0,0 +1,185 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "external_local_routing_test_service.hpp" + +external_local_routing_test_service::external_local_routing_test_service(bool _use_static_routing) : + app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + use_static_routing_(_use_static_routing), + blocked_(false), + number_received_messages_local_(0), + number_received_messages_external_(0), + offer_thread_(std::bind(&external_local_routing_test_service::run, this)) +{ +} + +bool external_local_routing_test_service::init() +{ + std::lock_guard its_lock(mutex_); + + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, + std::bind(&external_local_routing_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, + std::bind(&external_local_routing_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&external_local_routing_test_service::on_state, this, + std::placeholders::_1)); + + VSOMEIP_INFO << "Static routing " << (use_static_routing_ ? "ON" : "OFF"); + return true; +} + +void external_local_routing_test_service::start() +{ + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void external_local_routing_test_service::stop() +{ + VSOMEIP_INFO << "Stopping..."; + app_->clear_all_handler(); + app_->stop(); +} + +void external_local_routing_test_service::join_offer_thread() +{ + offer_thread_.join(); +} + +void external_local_routing_test_service::offer() +{ + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void external_local_routing_test_service::stop_offer() +{ + app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void external_local_routing_test_service::on_state(vsomeip::state_type_e _state) +{ + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : + "deregistered."); + + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + if(!is_registered_) + { + std::lock_guard its_lock(mutex_); + is_registered_ = true; + blocked_ = true; + // "start" the run method thread + condition_.notify_one(); + } + } + else + { + is_registered_ = false; + } +} + +void external_local_routing_test_service::on_message( + const std::shared_ptr& _request) +{ + VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _request->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _request->get_session() << "]"; + + ASSERT_EQ(_request->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID); + ASSERT_EQ(_request->get_method(), vsomeip_test::TEST_SERVICE_METHOD_ID); + + // Check the protocol version this shall be set to 0x01 according to the spec. + // TR_SOMEIP_00052 + ASSERT_EQ(_request->get_protocol_version(), 0x01); + // Check the message type this shall be 0xx (REQUEST) according to the spec. + // TR_SOMEIP_00055 + ASSERT_EQ(_request->get_message_type(), vsomeip::message_type_e::MT_REQUEST); + + if(_request->get_client() == vsomeip_test::TEST_CLIENT_CLIENT_ID) + { + number_received_messages_local_++; + // check the session id. + ASSERT_EQ(_request->get_session(), + static_cast(number_received_messages_local_)); + } + else if (_request->get_client() == vsomeip_test::TEST_CLIENT_EXTERNAL_CLIENT_ID) + { + number_received_messages_external_++; + // check the session id. + ASSERT_EQ(_request->get_session(), + static_cast(number_received_messages_external_)); + } + + // send response + std::shared_ptr its_response = + vsomeip::runtime::get()->create_response(_request); + + app_->send(its_response); + + if(number_received_messages_local_ >= vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND + && number_received_messages_external_ >= vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND) + { + std::lock_guard its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); + } + ASSERT_LT(number_received_messages_local_, + vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND + 1); + ASSERT_LT(number_received_messages_external_, + vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND + 1); +} + +void external_local_routing_test_service::run() +{ + std::unique_lock its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); + + blocked_ = false; + if(use_static_routing_) + { + offer(); + } + + while (!blocked_) { + condition_.wait(its_lock); + } + + std::thread t2([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 2));}); + t2.join(); + app_->stop(); +} + +TEST(someip_external_local_routing_test, receive_ten_messages_over_local_and_external_socket) +{ + bool use_static_routing = true; + external_local_routing_test_service test_service(use_static_routing); + if (test_service.init()) { + test_service.start(); + test_service.join_offer_thread(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/routing_tests/external_local_routing_test_service.hpp b/test/network_tests/routing_tests/external_local_routing_test_service.hpp new file mode 100644 index 0000000..a25025e --- /dev/null +++ b/test/network_tests/routing_tests/external_local_routing_test_service.hpp @@ -0,0 +1,46 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef EXTERNALLOCALROUTINGTESTSERVICE_HPP_ +#define EXTERNALLOCALROUTINGTESTSERVICE_HPP_ +#include + +#include + +#include +#include +#include +#include + +#include "../someip_test_globals.hpp" + +class external_local_routing_test_service +{ +public: + external_local_routing_test_service(bool _use_static_routing); + bool init(); + void start(); + void stop(); + void offer(); + void stop_offer(); + void join_offer_thread(); + void on_state(vsomeip::state_type_e _state); + void on_message(const std::shared_ptr &_request); + void run(); + +private: + std::shared_ptr app_; + bool is_registered_; + bool use_static_routing_; + + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + std::uint32_t number_received_messages_local_; + std::uint32_t number_received_messages_external_; + std::thread offer_thread_; +}; + +#endif /* EXTERNALLOCALROUTINGTESTSERVICE_HPP_ */ diff --git a/test/network_tests/routing_tests/external_local_routing_test_service_start.sh b/test/network_tests/routing_tests/external_local_routing_test_service_start.sh new file mode 100755 index 0000000..81b2ef1 --- /dev/null +++ b/test/network_tests/routing_tests/external_local_routing_test_service_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=external_local_routing_test_service +export VSOMEIP_CONFIGURATION=external_local_routing_test_service.json +./external_local_routing_test_service diff --git a/test/network_tests/routing_tests/external_local_routing_test_starter.sh b/test/network_tests/routing_tests/external_local_routing_test_starter.sh new file mode 100755 index 0000000..c67114f --- /dev/null +++ b/test/network_tests/routing_tests/external_local_routing_test_starter.sh @@ -0,0 +1,121 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit sucessfully. + +FAIL=0 + +# Parameter 1: the pid to check +check_tcp_udp_sockets_are_open () +{ + # Check that the service does listen on at least one TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -lt 1 ] + then + ((FAIL+=1)) + fi +} + +# Parameter 1: the pid to check +check_tcp_udp_sockets_are_closed () +{ + # Check that the service does not listen on any TCP/UDP socket + # or has any active connection via a TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] + then + ((FAIL+=1)) + fi + + SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] + then + ((FAIL+=1)) + fi +} + +# Start the service +export VSOMEIP_APPLICATION_NAME=external_local_routing_test_service +export VSOMEIP_CONFIGURATION=external_local_routing_test_service.json +./external_local_routing_test_service & +SERIVCE_PID=$! +sleep 1; + +check_tcp_udp_sockets_are_open $SERIVCE_PID + +# Start the client (we reuse the one from the local_routing_test to check +# the local routing functionality). +export VSOMEIP_APPLICATION_NAME=local_routing_test_client +export VSOMEIP_CONFIGURATION=local_routing_test_client.json +./local_routing_test_client & +CLIENT_PID=$! + +check_tcp_udp_sockets_are_open $SERIVCE_PID +sleep 1 +check_tcp_udp_sockets_are_closed $CLIENT_PID + +# wait that local client finishes +sleep 2 + +# Display a message to show the user that he must now call the external client +# to finish the test successfully +kill -0 $CLIENT_PID &> /dev/null +CLIENT_STILL_THERE=$? +if [ $CLIENT_STILL_THERE -ne 0 ] +then + if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting external_local_routing_test_starter.sh on slave LXC" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./external_local_routing_test_client_external_start.sh\"" & + echo "remote ssh job id: $!" + elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_routing_test_client_external_start.sh" & + else + cat <create_application()), + request_(vsomeip::runtime::get()->create_request(_use_tcp)), + blocked_(false), + is_available_(false), + number_of_messages_to_send_(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND), + number_of_sent_messages_(0), + number_of_acknowledged_messages_(0), + sender_(std::bind(&local_routing_test_client::run, this)) +{ +} + +bool local_routing_test_client::init() +{ + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + + app_->register_state_handler( + std::bind(&local_routing_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, + std::bind(&local_routing_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&local_routing_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + return true; +} + +void local_routing_test_client::start() +{ + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void local_routing_test_client::stop() +{ + VSOMEIP_INFO << "Stopping..."; + app_->clear_all_handler(); + app_->stop(); +} + +void local_routing_test_client::join_sender_thread(){ + sender_.join(); + + ASSERT_EQ(number_of_sent_messages_, number_of_acknowledged_messages_); +} + +void local_routing_test_client::on_state(vsomeip::state_type_e _state) +{ + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); + } +} + +void local_routing_test_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) +{ + VSOMEIP_INFO << "Service [" << std::setw(4) << std::setfill('0') << std::hex + << _service << "." << _instance << "] is " + << (_is_available ? "available." : "NOT available."); + + if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service + && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) + { + if(is_available_ && !_is_available) + { + is_available_ = false; + } + else if(_is_available && !is_available_) + { + is_available_ = true; + send(); + } + } +} + +void local_routing_test_client::on_message(const std::shared_ptr& _response) +{ + VSOMEIP_INFO << "Received a response from Service [" << std::setw(4) + << std::setfill('0') << std::hex << _response->get_service() << "." + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_instance() << "] to Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_client() << "/" << std::setw(4) + << std::setfill('0') << std::hex << _response->get_session() << "]"; + number_of_acknowledged_messages_++; + if(number_of_acknowledged_messages_ == number_of_messages_to_send_) { + std::lock_guard its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); + } +} + +void local_routing_test_client::send() +{ + std::lock_guard its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); +} + +void local_routing_test_client::run() +{ + std::unique_lock its_lock(mutex_); + while (!blocked_) + { + condition_.wait(its_lock); + } + blocked_ = false; + request_->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request_->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + request_->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); + + for (uint32_t i = 0; i < number_of_messages_to_send_; i++) + { + app_->send(request_); + VSOMEIP_INFO << "Client/Session [" << std::setw(4) << std::setfill('0') + << std::hex << request_->get_client() << "/" << std::setw(4) + << std::setfill('0') << std::hex << request_->get_session() + << "] sent a request to Service [" << std::setw(4) + << std::setfill('0') << std::hex << request_->get_service() + << "." << std::setw(4) << std::setfill('0') << std::hex + << request_->get_instance() << "]"; + number_of_sent_messages_++; + } + blocked_ = false; + // wait until all messages have been acknowledged + while (!blocked_) + { + condition_.wait(its_lock); + } + stop(); +} + +TEST(someip_local_routing_test, send_ten_messages_to_service_and_receive_reply) +{ + bool use_tcp = false; + local_routing_test_client test_client_(use_tcp); + if (test_client_.init()) { + test_client_.start(); + test_client_.join_sender_thread(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/routing_tests/local_routing_test_client.hpp b/test/network_tests/routing_tests/local_routing_test_client.hpp new file mode 100644 index 0000000..7cc442a --- /dev/null +++ b/test/network_tests/routing_tests/local_routing_test_client.hpp @@ -0,0 +1,48 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef LOCALROUTINGTESTCLIENT_HPP_ +#define LOCALROUTINGTESTCLIENT_HPP_ + +#include + +#include + +#include +#include +#include +#include + +#include "../someip_test_globals.hpp" + +class local_routing_test_client +{ +public: + local_routing_test_client(bool _use_tcp); + bool init(); + void start(); + void stop(); + void join_sender_thread(); + void on_state(vsomeip::state_type_e _state); + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available); + void on_message(const std::shared_ptr &_response); + void send(); + void run(); + +private: + std::shared_ptr app_; + std::shared_ptr request_; + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + bool is_available_; + std::uint32_t number_of_messages_to_send_; + std::uint32_t number_of_sent_messages_; + std::uint32_t number_of_acknowledged_messages_; + std::thread sender_; +}; + +#endif /* LOCALROUTINGTESTCLIENT_HPP_ */ diff --git a/test/network_tests/routing_tests/local_routing_test_client.json b/test/network_tests/routing_tests/local_routing_test_client.json new file mode 100644 index 0000000..e3521c8 --- /dev/null +++ b/test/network_tests/routing_tests/local_routing_test_client.json @@ -0,0 +1,38 @@ +{ + "unicast" : "127.0.0.1", + "netmask" : "255.255.255.0", + "diagnosis":"0x12", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "true", + "path" : "/var/log/vsomeip.log" + }, + + "dlt" : "true" + }, + + "applications" : + [ + { + "name" : "local_routing_test_client", + "id" : "0x1255" + } + ], + + "services" : + [ + ], + + "routing" : "routingmanagerd", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30491", + "protocol" : "udp" + } +} \ No newline at end of file diff --git a/test/network_tests/routing_tests/local_routing_test_client_start.sh b/test/network_tests/routing_tests/local_routing_test_client_start.sh new file mode 100755 index 0000000..ed4023e --- /dev/null +++ b/test/network_tests/routing_tests/local_routing_test_client_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=local_routing_test_client +export VSOMEIP_CONFIGURATION=local_routing_test_client.json +./local_routing_test_client diff --git a/test/network_tests/routing_tests/local_routing_test_service.cpp b/test/network_tests/routing_tests/local_routing_test_service.cpp new file mode 100644 index 0000000..6408057 --- /dev/null +++ b/test/network_tests/routing_tests/local_routing_test_service.cpp @@ -0,0 +1,164 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "local_routing_test_service.hpp" + +local_routing_test_service::local_routing_test_service(bool _use_static_routing) : + app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + use_static_routing_(_use_static_routing), + blocked_(false), + number_of_received_messages_(0), + offer_thread_(std::bind(&local_routing_test_service::run, this)) +{ +} + +bool local_routing_test_service::init() +{ + std::lock_guard its_lock(mutex_); + + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, + std::bind(&local_routing_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&local_routing_test_service::on_state, this, + std::placeholders::_1)); + + VSOMEIP_INFO << "Static routing " << (use_static_routing_ ? "ON" : "OFF"); + return true; +} + +void local_routing_test_service::start() +{ + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void local_routing_test_service::stop() +{ + VSOMEIP_INFO << "Stopping..."; + app_->clear_all_handler(); + app_->stop(); +} + +void local_routing_test_service::join_offer_thread() +{ + offer_thread_.join(); +} + +void local_routing_test_service::offer() +{ + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void local_routing_test_service::stop_offer() +{ + app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void local_routing_test_service::on_state(vsomeip::state_type_e _state) +{ + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : + "deregistered."); + + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + if(!is_registered_) + { + is_registered_ = true; + std::lock_guard its_lock(mutex_); + blocked_ = true; + // "start" the run method thread + condition_.notify_one(); + } + } + else + { + is_registered_ = false; + } +} + +void local_routing_test_service::on_message(const std::shared_ptr& _request) +{ + VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _request->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _request->get_session() << "]"; + + number_of_received_messages_++; + + ASSERT_EQ(_request->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID); + ASSERT_EQ(_request->get_method(), vsomeip_test::TEST_SERVICE_METHOD_ID); + + // Check the protocol version this shall be set to 0x01 according to the spec. + // TR_SOMEIP_00052 + ASSERT_EQ(_request->get_protocol_version(), 0x01); + // Check the message type this shall be 0xx (REQUEST) according to the spec. + // TR_SOMEIP_00055 + ASSERT_EQ(_request->get_message_type(), vsomeip::message_type_e::MT_REQUEST); + + // check the session id. + ASSERT_EQ(_request->get_session(), static_cast(number_of_received_messages_)); + + + // send response + std::shared_ptr its_response = + vsomeip::runtime::get()->create_response(_request); + + app_->send(its_response); + + if(number_of_received_messages_ >= vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND) + { + std::lock_guard its_lock(mutex_); + blocked_ =true; + condition_.notify_one(); + } + ASSERT_LT(number_of_received_messages_, + vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND + 1); +} + +void local_routing_test_service::run() +{ + std::unique_lock its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); + + blocked_ = false; + if(use_static_routing_) + { + offer(); + } + while (!blocked_) + condition_.wait(its_lock); + + std::thread t2([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 5));}); + t2.join(); + app_->stop(); +} + +TEST(someip_local_routing_test, receive_ten_messages_over_local_uds_socket) +{ + bool use_static_routing = true; + local_routing_test_service test_service(use_static_routing); + if (test_service.init()) { + test_service.start(); + test_service.join_offer_thread(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/routing_tests/local_routing_test_service.hpp b/test/network_tests/routing_tests/local_routing_test_service.hpp new file mode 100644 index 0000000..531fdb7 --- /dev/null +++ b/test/network_tests/routing_tests/local_routing_test_service.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef LOCALROUTINGTESTSERVICE_HPP_ +#define LOCALROUTINGTESTSERVICE_HPP_ +#include + +#include + +#include +#include +#include +#include + +#include "../someip_test_globals.hpp" + +class local_routing_test_service +{ +public: + local_routing_test_service(bool _use_static_routing); + bool init(); + void start(); + void stop(); + void offer(); + void stop_offer(); + void join_offer_thread(); + void on_state(vsomeip::state_type_e _state); + void on_message(const std::shared_ptr &_request); + void run(); + +private: + std::shared_ptr app_; + bool is_registered_; + bool use_static_routing_; + + bool blocked_; + std::uint32_t number_of_received_messages_; + std::mutex mutex_; + std::condition_variable condition_; + std::thread offer_thread_; +}; + +#endif /* LOCALROUTINGTESTSERVICE_HPP_ */ diff --git a/test/network_tests/routing_tests/local_routing_test_service.json b/test/network_tests/routing_tests/local_routing_test_service.json new file mode 100644 index 0000000..6b7e11d --- /dev/null +++ b/test/network_tests/routing_tests/local_routing_test_service.json @@ -0,0 +1,41 @@ +{ + "unicast" : "127.0.0.1", + "diagnosis":"0x12", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/tmp/vsomeip.log" + }, + + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "local_routing_test_service", + "id" : "0x1277" + } + ], + + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678" + } + ], + + "routing" : "routingmanagerd", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp" + } +} diff --git a/test/network_tests/routing_tests/local_routing_test_service_start.sh b/test/network_tests/routing_tests/local_routing_test_service_start.sh new file mode 100755 index 0000000..c59364c --- /dev/null +++ b/test/network_tests/routing_tests/local_routing_test_service_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=local_routing_test_service +export VSOMEIP_CONFIGURATION=local_routing_test_service.json +./local_routing_test_service diff --git a/test/network_tests/second_address_tests/conf/second_address_test_master_client.json.in b/test/network_tests/second_address_tests/conf/second_address_test_master_client.json.in new file mode 100644 index 0000000..542480f --- /dev/null +++ b/test/network_tests/second_address_tests/conf/second_address_test_master_client.json.in @@ -0,0 +1,32 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications" : + [ + { + "name" : "second_address_test_client", + "id" : "0x1210", + "max_dispatch_time" : "1000" + } + ], + "routing":"routingmanagerd", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.50.1", + "port":"30490", + "protocol":"udp", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/second_address_tests/conf/second_address_test_master_service_udp.json.in b/test/network_tests/second_address_tests/conf/second_address_test_master_service_udp.json.in new file mode 100644 index 0000000..1b45898 --- /dev/null +++ b/test/network_tests/second_address_tests/conf/second_address_test_master_service_udp.json.in @@ -0,0 +1,40 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications" : + [ + { + "name" : "second_address_test_service", + "id" : "0x3489", + "max_dispatch_time" : "1000" + } + ], + "services": + [ + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30001" + } + ], + "routing":"routingmanagerd", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.50.1", + "port":"30490", + "protocol":"udp", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/second_address_tests/conf/second_address_test_slave_client.json.in b/test/network_tests/second_address_tests/conf/second_address_test_slave_client.json.in new file mode 100644 index 0000000..303bfae --- /dev/null +++ b/test/network_tests/second_address_tests/conf/second_address_test_slave_client.json.in @@ -0,0 +1,32 @@ +{ + "unicast":"@TEST_IP_SLAVE_SECOND@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications" : + [ + { + "name" : "second_address_test_client", + "id" : "0x1210", + "max_dispatch_time" : "1000" + } + ], + "routing":"routingmanagerd", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.50.1", + "port":"30490", + "protocol":"udp", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/second_address_tests/conf/second_address_test_slave_service_udp.json.in b/test/network_tests/second_address_tests/conf/second_address_test_slave_service_udp.json.in new file mode 100644 index 0000000..9a7c062 --- /dev/null +++ b/test/network_tests/second_address_tests/conf/second_address_test_slave_service_udp.json.in @@ -0,0 +1,40 @@ +{ + "unicast":"@TEST_IP_SLAVE_SECOND@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications" : + [ + { + "name" : "second_address_test_service", + "id" : "0x3489", + "max_dispatch_time" : "1000" + } + ], + "services": + [ + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30001" + } + ], + "routing":"routingmanagerd", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.50.1", + "port":"30490", + "protocol":"udp", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/second_address_tests/conf/second_address_test_slave_starter.sh.in b/test/network_tests/second_address_tests/conf/second_address_test_slave_starter.sh.in new file mode 100755 index 0000000..5694aa6 --- /dev/null +++ b/test/network_tests/second_address_tests/conf/second_address_test_slave_starter.sh.in @@ -0,0 +1,60 @@ +#!/bin/bash +# Copyright (C) 2015-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 + +if [ $# -lt 2 ] +then + echo "Please pass a operation and communication mode to this script." + echo "For example: $0 CLIENT UDP" + echo "Valid operation modes include [SERVICE, CLIENT]" + echo "Valid communication modes include [UDP, TCP]" + exit 1 +fi + +OPERATIONMODE=$1 +COMMUNICATIONMODE=$2 + +# Add second IP address to interface +ip addr add @TEST_IP_SLAVE_SECOND@/32 dev eth0 + +if [ "$OPERATIONMODE" = "CLIENT" ]; then + SLAVE_APPLICATION=second_address_test_client + export VSOMEIP_CONFIGURATION=second_address_test_slave_client.json + +elif [ "$OPERATIONMODE" = "SERVICE" ]; then + SLAVE_APPLICATION=second_address_test_service + + if [ "$COMMUNICATIONMODE" = "TCP" ]; then + export VSOMEIP_CONFIGURATION=second_address_test_slave_service_tcp.json + elif [ "$COMMUNICATIONMODE" = "UDP" ]; then + export VSOMEIP_CONFIGURATION=second_address_test_slave_service_udp.json + fi +fi + +../../examples/routingmanagerd/routingmanagerd & +PID_VSOMEIPD=$! + +./$SLAVE_APPLICATION $COMMUNICATIONMODE & +PID_SLAVE=$! + +# Wait until all slaves are finished +for job in $PID_SLAVE +do + # Fail gets incremented if a client exits with a non-zero exit code + echo "waiting for $job" + wait $job || FAIL=$(($FAIL+1)) +done + +# kill the services +kill $PID_VSOMEIPD +sleep 1 + +# Delete second IP address +ip addr del @TEST_IP_SLAVE_SECOND@/32 dev eth0 + +# Check if everything went well +exit $FAIL diff --git a/test/network_tests/second_address_tests/second_address_test_client.cpp b/test/network_tests/second_address_tests/second_address_test_client.cpp new file mode 100644 index 0000000..9f05706 --- /dev/null +++ b/test/network_tests/second_address_tests/second_address_test_client.cpp @@ -0,0 +1,353 @@ +// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "second_address_test_globals.hpp" + +class second_address_test_client { +public: + second_address_test_client(struct second_address_test::service_info _service_info, bool _use_tcp) : + service_info_(_service_info), + use_tcp_(_use_tcp), + app_(vsomeip::runtime::get()->create_application("second_address_test_client")), + send_thread_(std::bind(&second_address_test_client::send, this)) { + + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + + app_->register_state_handler( + std::bind(&second_address_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.request_method_id, + std::bind(&second_address_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.event_id, + std::bind(&second_address_test_client::on_notification, this, + std::placeholders::_1, false)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.selective_event_id, + std::bind(&second_address_test_client::on_notification, this, + std::placeholders::_1, true)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.shutdown_method_id, + std::bind(&second_address_test_client::on_shutdown_method_called, this, + std::placeholders::_1)); + + // register availability for all other services and request their event. + app_->register_availability_handler(service_info_.service_id, + service_info_.instance_id, + std::bind(&second_address_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + app_->request_service(service_info_.service_id, + service_info_.instance_id); + + app_->register_subscription_status_handler(service_info_.service_id, + service_info_.instance_id, service_info_.eventgroup_id, + service_info_.event_id, + std::bind(&second_address_test_client::on_subscription_status_changed, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4, + std::placeholders::_5, false)); + + app_->register_subscription_status_handler(service_info_.service_id, + service_info_.instance_id, service_info_.selective_eventgroup_id, + service_info_.selective_event_id, + std::bind(&second_address_test_client::on_subscription_status_changed, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4, + std::placeholders::_5, true)); + + app_->start(); + } + + ~second_address_test_client() { + send_thread_.join(); + } + + void subscribe() { + std::set its_eventgroups; + its_eventgroups.insert(service_info_.eventgroup_id); + + app_->request_event(service_info_.service_id, + service_info_.instance_id, service_info_.event_id, + its_eventgroups, vsomeip::event_type_e::ET_EVENT); + + its_eventgroups.clear(); + its_eventgroups.insert(service_info_.selective_eventgroup_id); + + app_->request_event(service_info_.service_id, + service_info_.instance_id, service_info_.selective_event_id, + its_eventgroups, vsomeip::event_type_e::ET_SELECTIVE_EVENT); + + app_->subscribe(service_info_.service_id, service_info_.instance_id, + service_info_.eventgroup_id); + + app_->subscribe(service_info_.service_id, service_info_.instance_id, + service_info_.selective_eventgroup_id); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_DEBUG << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered" : "deregistered") << " on client."; + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, + bool _is_available) { + + VSOMEIP_DEBUG << "Service [" << std::setw(4) + << std::setfill('0') << std::hex << _service << "." << _instance + << "] is " << (_is_available ? "available":"not available") << " on client."; + + if (_is_available) { + std::lock_guard its_lock(mutex_); + wait_until_service_available_ = false; + condition_.notify_one(); + } + } + + void on_message(const std::shared_ptr &_message) { + EXPECT_EQ(service_info_.service_id, _message->get_service()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + EXPECT_EQ(service_info_.request_method_id, _message->get_method()); + + std::lock_guard its_lock(mutex_); + auto its_payload = _message->get_payload(); + std::uint32_t data = static_cast(its_payload->get_data()[0]); + + EXPECT_EQ(reply_received_, data); + + wait_until_reply_received_ = false; + reply_received_++; + condition_.notify_one(); + } + + void on_notification(const std::shared_ptr &_message, + bool _selective) { + EXPECT_EQ(service_info_.service_id, _message->get_service()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + + static vsomeip::length_t length_last_received_msg(0); + EXPECT_GT(_message->get_payload()->get_length(), length_last_received_msg); + length_last_received_msg = _message->get_payload()->get_length(); + + if (_selective) { + EXPECT_EQ(service_info_.selective_event_id, _message->get_method()); + + if (++number_selective_events_received_ == second_address_test::number_of_events_to_send) { + std::lock_guard its_lock(mutex_); + wait_until_selective_events_received_ = false; + condition_.notify_one(); + } + } else { + EXPECT_EQ(service_info_.event_id, _message->get_method()); + + if (++number_events_received_ == second_address_test::number_of_events_to_send) { + std::lock_guard its_lock(mutex_); + wait_until_events_received_ = false; + condition_.notify_one(); + } + } + } + + void on_subscription_status_changed(const vsomeip::service_t _service, + const vsomeip::instance_t _instance, + const vsomeip::eventgroup_t _eventgroup, + const vsomeip::event_t _event, + const uint16_t error_code, + bool _selective) { + + VSOMEIP_DEBUG << "Subscription status changed on client"; + + EXPECT_EQ(service_info_.service_id, _service); + EXPECT_EQ(service_info_.instance_id, _instance); + EXPECT_TRUE((error_code == 0x0u || error_code == 0x7u)); + + if (_selective) { + EXPECT_EQ(service_info_.selective_eventgroup_id, _eventgroup); + EXPECT_EQ(service_info_.selective_event_id, _event); + + if (error_code == 0x0u) { // accepted + std::lock_guard its_lock(mutex_); + wait_until_selective_subscription_accepted_ = false; + condition_.notify_one(); + } + + } else { + EXPECT_EQ(service_info_.eventgroup_id, _eventgroup); + EXPECT_EQ(service_info_.event_id, _event); + + if (error_code == 0x0u) { // accepted + std::lock_guard its_lock(mutex_); + wait_until_subscription_accepted_ = false; + condition_.notify_one(); + } + } + } + + void on_shutdown_method_called(const std::shared_ptr &_message) { + EXPECT_EQ(service_info_.service_id, _message->get_service()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + EXPECT_EQ(service_info_.shutdown_method_id, _message->get_method()); + + std::lock_guard its_lock(mutex_); + wait_until_shutdown_reply_received_ = false; + condition_.notify_one(); + } + + void send() { + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + while (wait_until_service_available_) { + condition_.wait(its_lock); + } + + auto its_message = vsomeip::runtime::get()->create_request(use_tcp_); + its_message->set_service(service_info_.service_id); + its_message->set_instance(service_info_.instance_id); + its_message->set_method(service_info_.request_method_id); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST); + + auto its_payload = vsomeip::runtime::get()->create_payload(); + + VSOMEIP_DEBUG << "Client sending request messages"; + + for (std::uint32_t index = 0; index < second_address_test::number_of_messages_to_send; index++) { + vsomeip::byte_t *msg_payload = reinterpret_cast(&index); + its_payload->set_data(msg_payload, sizeof(index)); + its_message->set_payload(its_payload); + app_->send(its_message); + + wait_until_reply_received_ = true; + message_sent_++; + + while (wait_until_reply_received_) { + condition_.wait(its_lock); + } + } + + VSOMEIP_DEBUG << "Client subscribing events"; + + subscribe(); + while (wait_until_subscription_accepted_ || wait_until_selective_subscription_accepted_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "Client requesting event notification"; + + its_message->set_method(service_info_.notify_method_id); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + its_payload->set_data(&second_address_test::number_of_events_to_send, 1); + its_message->set_payload(its_payload); + app_->send(its_message); + + VSOMEIP_DEBUG << "Client waiting event notification"; + + while (wait_until_events_received_ || wait_until_selective_events_received_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "Client shutting down the service"; + + // shutdown service + its_message->set_method(service_info_.shutdown_method_id); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST); + app_->send(its_message); + + while (wait_until_shutdown_reply_received_) { + if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { + VSOMEIP_ERROR << "Shutdown request wasn't answered in time!"; + break; + } + } + + VSOMEIP_INFO << "Client going down"; + app_->clear_all_handler(); + app_->stop(); + } + + +private: + struct second_address_test::service_info service_info_; + bool use_tcp_; + std::shared_ptr app_; + + bool wait_until_registered_ = true; + bool wait_until_service_available_ = true; + bool wait_until_subscription_accepted_ = true; + bool wait_until_selective_subscription_accepted_ = true; + bool wait_until_shutdown_reply_received_ = true; + bool wait_until_reply_received_ = true; + bool wait_until_events_received_ = true; + bool wait_until_selective_events_received_ = true; + std::mutex mutex_; + std::condition_variable condition_; + + std::thread send_thread_; + std::uint32_t message_sent_ = 0; + std::uint32_t reply_received_ = 0; + std::uint32_t number_events_received_ = 0; + std::uint32_t number_selective_events_received_ = 0; +}; + +static bool use_tcp = false; + +TEST(someip_event_test, communicate_using_second_address) +{ + second_address_test_client its_sample(second_address_test::service, use_tcp); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if (argc < 2) { + std::cerr << "Please specify a communication mode, like: " << argv[0] << " TCP" << std::endl; + std::cerr << "Valid communication modes are UDP or TCP" << std::endl; + return 1; + } + + if (std::string("TCP")== std::string(argv[1])) { + use_tcp = true; + } else if (std::string("UDP")== std::string(argv[1])) { + use_tcp = false; + } + + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/second_address_tests/second_address_test_globals.hpp b/test/network_tests/second_address_tests/second_address_test_globals.hpp new file mode 100644 index 0000000..1909fcd --- /dev/null +++ b/test/network_tests/second_address_tests/second_address_test_globals.hpp @@ -0,0 +1,29 @@ +// Copyright (C) 2014-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef SECOND_ADDRESS_TEST_GLOBALS_HPP_ +#define SECOND_ADDRESS_TEST_GLOBALS_HPP_ + +namespace second_address_test { + +struct service_info { + vsomeip::service_t service_id; + vsomeip::instance_t instance_id; + vsomeip::eventgroup_t eventgroup_id; + vsomeip::event_t event_id; + vsomeip::eventgroup_t selective_eventgroup_id; + vsomeip::event_t selective_event_id; + vsomeip::method_t request_method_id; + vsomeip::method_t notify_method_id; + vsomeip::method_t shutdown_method_id; +}; + +struct service_info service = { 0x3333, 0x1, 0x1, 0x3301, 0x2, 0x3302, 0x1111, 0x2222, 0x1404 }; + +static constexpr std::uint32_t number_of_messages_to_send = 150; +static constexpr std::uint8_t number_of_events_to_send = 150; +} + +#endif /* SECOND_ADDRESS_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/second_address_tests/second_address_test_master_starter.sh b/test/network_tests/second_address_tests/second_address_test_master_starter.sh new file mode 100755 index 0000000..03d726b --- /dev/null +++ b/test/network_tests/second_address_tests/second_address_test_master_starter.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 + +if [ $# -lt 2 ] +then + echo "Please pass a operation and communication mode to this script." + echo "For example: $0 SERVICE UDP" + echo "Valid operation modes include [SERVICE, CLIENT]" + echo "Valid communication modes include [UDP, TCP]" + exit 1 +fi + +OPERATIONMODE=$1 +COMMUNICATIONMODE=$2 + +if [ "$OPERATIONMODE" = "SERVICE" ]; then + MASTER_APPLICATION=second_address_test_service + SLAVE_OPERATIONMODE="CLIENT" + + if [ "$COMMUNICATIONMODE" = "TCP" ]; then + export VSOMEIP_CONFIGURATION=second_address_test_master_service_tcp.json + elif [ "$COMMUNICATIONMODE" = "UDP" ]; then + export VSOMEIP_CONFIGURATION=second_address_test_master_service_udp.json + fi + +elif [ "$OPERATIONMODE" = "CLIENT" ]; then + MASTER_APPLICATION=second_address_test_client + SLAVE_OPERATIONMODE="SERVICE" + export VSOMEIP_CONFIGURATION=second_address_test_master_client.json +fi + +../../examples/routingmanagerd/routingmanagerd & +PID_VSOMEIPD=$! + +./$MASTER_APPLICATION $COMMUNICATIONMODE & +PID_MASTER=$! + +sleep 1 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting offer test on slave LXC second_address_test_slave_starter.sh" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./second_address_test_slave_starter.sh $SLAVE_OPERATIONMODE $COMMUNICATIONMODE\"" & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS; sleep 10; ./second_address_test_slave_starter.sh $SLAVE_OPERATIONMODE $COMMUNICATIONMODE" & +else +cat < +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "second_address_test_globals.hpp" + +class second_address_test_service { +public: + second_address_test_service(struct second_address_test::service_info _service_info) : + service_info_(_service_info), + app_(vsomeip::runtime::get()->create_application("second_address_test_service")), + offer_thread_(std::bind(&second_address_test_service::run, this)) { + + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + + app_->register_state_handler( + std::bind(&second_address_test_service::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.request_method_id, + std::bind(&second_address_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.notify_method_id, + std::bind(&second_address_test_service::on_notify, this, + std::placeholders::_1)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.shutdown_method_id, + std::bind(&second_address_test_service::on_shutdown_method_called, this, + std::placeholders::_1)); + + app_->register_subscription_handler(service_info_.service_id, + service_info_.instance_id, service_info_.eventgroup_id, + std::bind(&second_address_test_service::subscription_handler, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4)); + + app_->register_subscription_handler(service_info_.service_id, + service_info_.instance_id, service_info_.selective_eventgroup_id, + std::bind(&second_address_test_service::selective_subscription_handler, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4)); + + app_->start(); + } + + ~second_address_test_service() { + offer_thread_.join(); + } + + void stop() { + app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); + app_->clear_all_handler(); + app_->stop(); + } + +private: + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered" : "deregistered") << " on service."; + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_shutdown_method_called(const std::shared_ptr &_message) { + app_->send(vsomeip::runtime::get()->create_response(_message)); + + VSOMEIP_WARNING << "************************************************************"; + VSOMEIP_WARNING << "Shutdown method called on service -> going down!"; + VSOMEIP_WARNING << "************************************************************"; + + std::lock_guard its_lock(mutex_); + wait_until_shutdown_method_called_ = false; + condition_.notify_one(); + } + + void on_message(const std::shared_ptr &_message) { + EXPECT_EQ(service_info_.service_id, _message->get_service()); + EXPECT_EQ(service_info_.request_method_id, _message->get_method()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + + std::shared_ptr response = vsomeip::runtime::get()->create_response(_message); + response->set_payload(_message->get_payload()); + app_->send(response); + + std::lock_guard its_lock(mutex_); + messages_received_++; + + if (messages_received_ == second_address_test::number_of_messages_to_send) { + wait_until_receive_messages_ = false; + condition_.notify_one(); + } + } + + void on_notify(const std::shared_ptr &_message) { + EXPECT_EQ(service_info_.service_id, _message->get_service()); + EXPECT_EQ(service_info_.notify_method_id, _message->get_method()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + + auto its_payload = _message->get_payload(); + notifications_to_send_ = its_payload->get_data()[0]; + + std::lock_guard its_lock(mutex_); + wait_until_notify_method_called_ = false; + condition_.notify_one(); + } + + void offer() { + app_->offer_service(service_info_.service_id, service_info_.instance_id); + + std::set its_eventgroups; + its_eventgroups.insert(service_info_.eventgroup_id); + + app_->offer_event(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_eventgroups, + vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + + its_eventgroups.clear(); + its_eventgroups.insert(service_info_.selective_eventgroup_id); + + app_->offer_event(service_info_.service_id, service_info_.instance_id, + service_info_.selective_event_id, its_eventgroups, + vsomeip::event_type_e::ET_SELECTIVE_EVENT, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); + } + + void notify() { + EXPECT_TRUE(client_subscribed_); + EXPECT_TRUE(client_subscribed_selective_); + auto its_payload = vsomeip::runtime::get()->create_payload(); + + std::uint32_t i = 0; + + for (; i < notifications_to_send_; i++) { + its_payload->set_data(std::vector(i+1, 0x55)); + app_->notify(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_payload); + } + + for (; i < 2 * notifications_to_send_; i++) { + its_payload->set_data(std::vector(i+1, 0x55)); + app_->notify_one(service_info_.service_id, service_info_.instance_id, + service_info_.selective_event_id, its_payload, client_id_); + } + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + + while (wait_until_receive_messages_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "Service waiting for notify method has been called"; + while (wait_until_notify_method_called_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "Service notifying events"; + notify(); + + while (wait_until_shutdown_method_called_) { + condition_.wait(its_lock); + } + + its_lock.unlock(); + stop(); + } + + bool subscription_handler(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) { + (void)_uid; + (void)_gid; + VSOMEIP_DEBUG << __func__ << ": client 0x" << std::hex << std::setw(4) << std::setfill('0') << _client + << ((_subscribed) ? " subscribed" : "unsubscribed") << " on service."; + client_subscribed_ = _subscribed; + return true; + } + + bool selective_subscription_handler(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) { + (void)_uid; + (void)_gid; + VSOMEIP_DEBUG << __func__ << ": client 0x" << std::hex << std::setw(4) << std::setfill('0') << _client + << ((_subscribed) ? " subscribed" : "unsubscribed") << " on service."; + client_subscribed_selective_ = _subscribed; + client_id_ = _client; + return true; + } + +private: + struct second_address_test::service_info service_info_; + std::shared_ptr app_; + + bool wait_until_registered_ = true; + bool wait_until_receive_messages_ = true; + bool wait_until_notify_method_called_ = true; + bool wait_until_shutdown_method_called_ = true; + bool client_subscribed_ = false; + bool client_subscribed_selective_ = false; + vsomeip::client_t client_id_ = 0; + std::uint32_t messages_received_ = 0; + std::uint8_t notifications_to_send_ = 0; + std::mutex mutex_; + std::condition_variable condition_; + std::thread offer_thread_; +}; + +TEST(someip_second_address_test, test_communication_with_client) +{ + second_address_test_service its_sample(second_address_test::service); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/security_tests/conf/security_test_config_client_external_allow.json.in b/test/network_tests/security_tests/conf/security_test_config_client_external_allow.json.in new file mode 100644 index 0000000..e73f3db --- /dev/null +++ b/test/network_tests/security_tests/conf/security_test_config_client_external_allow.json.in @@ -0,0 +1,90 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "info", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "client-sample", + "id" : "0x1255" + }, + { + "name" : "routingmanagerd", + "id" : "0x2222" + } + ], + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + }, + { + "service" : "0x111", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + }, + { + "service" : "0x1234", + "instance" : "0x02", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + } + ], + "security" : + { + "check_credentials" : "true", + "allow_remote_clients" : "true", + "policies" : + [ + { + "credentials" : { "uid" : "@TEST_UID@", "gid" : "@TEST_GID@" }, + "allow" : + { + "requests": + [ + { + "service" : "0x1234", + "instances" : + [ + { + "ids" : ["0x5678"], + "methods" : [ {"first" : "0x8421", "last" : "0x8422" }, "0x8001", "0x7777" ] + } + ] + } + ] + } + } + ] + }, + "routing" : "routingmanagerd", + "routing-credentials" : + { + "uid" : "@TEST_UID@", + "gid" : "@TEST_GID@" + }, + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "100", + "repetitions_base_delay" : "200", + "repetitions_max" : "3", + "ttl" : "3", + "cyclic_offer_delay" : "2000", + "request_response_delay" : "1500" + } +} diff --git a/test/network_tests/security_tests/conf/security_test_config_client_external_deny.json.in b/test/network_tests/security_tests/conf/security_test_config_client_external_deny.json.in new file mode 100644 index 0000000..1161f4f --- /dev/null +++ b/test/network_tests/security_tests/conf/security_test_config_client_external_deny.json.in @@ -0,0 +1,90 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "info", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "client-sample", + "id" : "0x1255" + }, + { + "name" : "routingmanagerd", + "id" : "0x2222" + } + ], + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + }, + { + "service" : "0x111", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + }, + { + "service" : "0x1234", + "instance" : "0x02", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + } + ], + "security" : + { + "check_credentials" : "true", + "allow_remote_clients" : "false", + "policies" : + [ + { + "credentials" : { "uid" : "@TEST_UID@", "gid" : "@TEST_GID@" }, + "allow" : + { + "requests": + [ + { + "service" : "0x1234", + "instances" : + [ + { + "ids" : ["0x5678"], + "methods" : [ {"first" : "0x8421", "last" : "0x8422" }, "0x8001", "0x7777" ] + } + ] + } + ] + } + } + ] + }, + "routing" : "routingmanagerd", + "routing-credentials" : + { + "uid" : "@TEST_UID@", + "gid" : "@TEST_GID@" + }, + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "100", + "repetitions_base_delay" : "200", + "repetitions_max" : "3", + "ttl" : "3", + "cyclic_offer_delay" : "2000", + "request_response_delay" : "1500" + } +} diff --git a/test/network_tests/security_tests/conf/security_test_config_service_external_allow.json.in b/test/network_tests/security_tests/conf/security_test_config_service_external_allow.json.in new file mode 100644 index 0000000..4d9129a --- /dev/null +++ b/test/network_tests/security_tests/conf/security_test_config_service_external_allow.json.in @@ -0,0 +1,84 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "info", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "service-sample", + "id" : "0x1277" + }, + { + "name" : "routingmanagerd", + "id" : "0x1111" + } + ], + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + }, + { + "service" : "0x111", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + }, + { + "service" : "0x1234", + "instance" : "0x02", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + } + ], + "security" : + { + "check_credentials" : "true", + "allow_remote_clients" : "true", + "policies" : + [ + { + "credentials" : { "uid" : "@TEST_UID@", "gid" : "@TEST_GID@" }, + "allow" : + { + "offers": + [ + { + "service" : "0x1234", + "instance" : "0x5678" + } + ] + } + } + ] + }, + "routing" : "routingmanagerd", + "routing-credentials" : + { + "uid" : "@TEST_UID@", + "gid" : "@TEST_GID@" + }, + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "100", + "repetitions_base_delay" : "200", + "repetitions_max" : "3", + "ttl" : "3", + "cyclic_offer_delay" : "2000", + "request_response_delay" : "1500" + } +} diff --git a/test/network_tests/security_tests/conf/security_test_config_service_external_deny.json.in b/test/network_tests/security_tests/conf/security_test_config_service_external_deny.json.in new file mode 100644 index 0000000..769b04f --- /dev/null +++ b/test/network_tests/security_tests/conf/security_test_config_service_external_deny.json.in @@ -0,0 +1,84 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "info", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "service-sample", + "id" : "0x1277" + }, + { + "name" : "routingmanagerd", + "id" : "0x1111" + } + ], + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + }, + { + "service" : "0x111", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + }, + { + "service" : "0x1234", + "instance" : "0x02", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509" + } + ], + "security" : + { + "check_credentials" : "true", + "allow_remote_clients" : "false", + "policies" : + [ + { + "credentials" : { "uid" : "@TEST_UID@", "gid" : "@TEST_GID@" }, + "allow" : + { + "offers": + [ + { + "service" : "0x1234", + "instance" : "0x5678" + } + ] + } + } + ] + }, + "routing" : "routingmanagerd", + "routing-credentials" : + { + "uid" : "@TEST_UID@", + "gid" : "@TEST_GID@" + }, + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "100", + "repetitions_base_delay" : "200", + "repetitions_max" : "3", + "ttl" : "3", + "cyclic_offer_delay" : "2000", + "request_response_delay" : "1500" + } +} diff --git a/test/network_tests/security_tests/conf/security_test_local_config.json.in b/test/network_tests/security_tests/conf/security_test_local_config.json.in new file mode 100644 index 0000000..60036f8 --- /dev/null +++ b/test/network_tests/security_tests/conf/security_test_local_config.json.in @@ -0,0 +1,78 @@ +{ + "unicast" : "localhost", + "logging" : + { + "level" : "info", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "service-sample", + "id" : "0x1277" + }, + { + "name" : "client-sample", + "id" : "0x1255" + }, + { + "name" : "routingmanagerd", + "id" : "0x1111" + } + ], + "security" : + { + "check_credentials" : "true", + "policies" : + [ + { + "credentials" : { "uid" : "@TEST_UID@", "gid" : "@TEST_GID@" }, + "allow" : + { + "offers": + [ + { + "service" : "0x1234", + "instance" : "0x5678" + } + ], + "requests": + [ + { + "service" : "0x1234", + "instances" : + [ + { + "ids" : ["0x5678"], + "methods" : [ {"first" : "0x8421", "last" : "0x8422" }, "0x8001", "0x7777" ] + } + ] + } + ] + } + } + ] + }, + "routing" : "routingmanagerd", + "routing-credentials" : + { + "uid" : "@TEST_UID@", + "gid" : "@TEST_GID@" + }, + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.244.224.245", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "100", + "repetitions_base_delay" : "200", + "repetitions_max" : "3", + "ttl" : "3", + "cyclic_offer_delay" : "2000", + "request_response_delay" : "1500" + } +} diff --git a/test/network_tests/security_tests/security_test_client.cpp b/test/network_tests/security_tests/security_test_client.cpp new file mode 100644 index 0000000..2890e74 --- /dev/null +++ b/test/network_tests/security_tests/security_test_client.cpp @@ -0,0 +1,278 @@ +// Copyright (C) 2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "security_test_client.hpp" + +static bool is_remote_test = false; +static bool remote_client_allowed = true; + +security_test_client::security_test_client(bool _test_external_communication, + bool _is_remote_client_allowed) + : app_(vsomeip::runtime::get()->create_application()), + is_available_(false), + sender_(std::bind(&security_test_client::run, this)), + received_responses_(0), + received_allowed_events_(0), + test_external_communication_(_test_external_communication), + is_remote_client_allowed_(_is_remote_client_allowed) { + +} + +bool security_test_client::init() { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + + app_->register_state_handler( + std::bind(&security_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, + std::bind(&security_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&security_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + app_->register_availability_handler(0x111, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&security_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + 0x02, + std::bind(&security_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + return true; +} + +void security_test_client::start() { + VSOMEIP_INFO << "Starting..."; + + app_->start(); +} + +void security_test_client::stop() { + VSOMEIP_INFO << "Stopping..."; + + if (is_remote_client_allowed_) { + shutdown_service(); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + app_->clear_all_handler(); + app_->stop(); +} + +void security_test_client::on_state(vsomeip::state_type_e _state) { + if(_state == vsomeip::state_type_e::ST_REGISTERED) { + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); + + // request not allowed service ID + app_->request_service(0x111, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); + + // request not allowed instance ID + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + 0x02, false); + + // request events of eventgroup 0x01 which holds events 0x8001 (allowed) and 0x8002 (denied) + std::set its_eventgroups; + its_eventgroups.insert(0x01); + app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8001), + its_eventgroups, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8002), + its_eventgroups, vsomeip::event_type_e::ET_FIELD, + vsomeip::reliability_type_e::RT_UNRELIABLE); + + app_->subscribe(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, 0x01, + vsomeip::DEFAULT_MAJOR, static_cast(0x8001)); + + app_->subscribe(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, 0x01, + vsomeip::DEFAULT_MAJOR, static_cast(0x8002)); + } +} + +void security_test_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + + VSOMEIP_INFO << std::hex << "Client 0x" << app_->get_client() + << " : Service [" << std::setw(4) << std::setfill('0') << std::hex + << _service << "." << _instance << "] is " + << (_is_available ? "available." : "NOT available."); + + // check that only the allowed service / instance ID gets available + if (_is_available) { + EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _service); + EXPECT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _instance); + } + + if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service + && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) { + std::unique_lock its_lock(mutex_); + if(is_available_ && !_is_available) { + is_available_ = false; + } + else if(_is_available && !is_available_) { + is_available_ = true; + condition_.notify_one(); + } + } +} + +void security_test_client::on_message(const std::shared_ptr &_response) { + VSOMEIP_INFO << "Received a response from Service [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() + << "." + << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() + << "] to Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() + << "/" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() + << "]"; + + if(_response->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _response->get_service()); + EXPECT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _response->get_instance()); + EXPECT_EQ(vsomeip_test::TEST_SERVICE_METHOD_ID, _response->get_method()); + + if (_response->get_service() == vsomeip_test::TEST_SERVICE_SERVICE_ID && + _response->get_instance() == vsomeip_test::TEST_SERVICE_INSTANCE_ID && + _response->get_method() == vsomeip_test::TEST_SERVICE_METHOD_ID) { + received_responses_++; + if (received_responses_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS) { + VSOMEIP_WARNING << std::hex << app_->get_client() + << ": Received all messages ~> going down!"; + } + } + } else if (_response->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + // check that only allowed event 0x8001 is received + EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _response->get_service()); + EXPECT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _response->get_instance()); + EXPECT_EQ(0x8001, _response->get_method()); + received_allowed_events_++; + } +} + +void security_test_client::run() { + for (uint32_t i = 0; i < vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS; ++i) { + { + std::unique_lock its_lock(mutex_); + while (!is_available_) + { + condition_.wait(its_lock); + } + } + + auto request = vsomeip::runtime::get()->create_request(false); + request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); + + // send a request which is allowed by policy -> expect answer + app_->send(request); + + // send a request with a not allowed method ID -> expect no answer + request->set_method(0x888); + app_->send(request); + + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + + if (!test_external_communication_) { + EXPECT_EQ(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS, + received_responses_); + EXPECT_EQ(received_allowed_events_, (uint32_t) 0x01); + } else if (test_external_communication_ && !is_remote_client_allowed_) { + EXPECT_EQ((uint32_t)0, received_responses_); + EXPECT_EQ((uint32_t)0, received_allowed_events_); + } else if (test_external_communication_ && is_remote_client_allowed_) { + EXPECT_EQ(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS, + received_responses_); + EXPECT_EQ(received_allowed_events_, (uint32_t) 0x01); + } + stop(); +} + +void security_test_client::join_sender_thread() +{ + if (sender_.joinable()) { + sender_.join(); + } +} + +void security_test_client::shutdown_service() { + auto request = vsomeip::runtime::get()->create_request(false); + request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); + app_->send(request); +} + +TEST(someip_security_test, basic_subscribe_request_response) +{ + security_test_client test_client(is_remote_test, remote_client_allowed); + if (test_client.init()) { + test_client.start(); + test_client.join_sender_thread(); + } +} + +int main(int argc, char** argv) { + + std::string test_remote("--remote"); + std::string test_local("--local"); + std::string test_allow_remote_client("--allow"); + std::string test_deny_remote_client("--deny"); + std::string help("--help"); + + int i = 1; + while (i < argc) + { + if(test_remote == argv[i]) + { + is_remote_test = true; + } + else if(test_local == argv[i]) + { + is_remote_test = false; + } + else if(test_allow_remote_client == argv[i]) + { + remote_client_allowed = true; + } + else if(test_deny_remote_client == argv[i]) + { + remote_client_allowed = false; + } + else if(help == argv[i]) + { + VSOMEIP_INFO << "Parameters:\n" + << "--remote: Run test between two hosts\n" + << "--local: Run test locally\n" + << "--allow: test is started with a policy that allows remote messages sent by this test client to the service\n" + << "--deny: test is started with a policy that denies remote messages sent by this test client to the service\n" + << "--help: print this help"; + } + i++; + } + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/network_tests/security_tests/security_test_client.hpp b/test/network_tests/security_tests/security_test_client.hpp new file mode 100644 index 0000000..df2acc8 --- /dev/null +++ b/test/network_tests/security_tests/security_test_client.hpp @@ -0,0 +1,55 @@ + +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef SECURITY_TEST_CLIENT_HPP +#define SECURITY_TEST_CLIENT_HPP + +#include + +#include + +#include "../someip_test_globals.hpp" + +#include +#include +#include +#include + +class security_test_client { +public: + security_test_client(bool _test_external_communication, + bool _is_remote_client_allowed); + bool init(); + void start(); + void stop(); + + void on_state(vsomeip::state_type_e _state); + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available); + void on_message(const std::shared_ptr &_response); + + void run(); + void join_sender_thread(); + +private: + void shutdown_service(); + + std::shared_ptr app_; + + std::mutex mutex_; + std::condition_variable condition_; + bool is_available_; + + std::thread sender_; + + std::atomic received_responses_; + std::atomic received_allowed_events_; + + bool test_external_communication_; + bool is_remote_client_allowed_; +}; + +#endif // SECURITY_TEST_CLIENT_HPP diff --git a/test/network_tests/security_tests/security_test_external_master_start.sh b/test/network_tests/security_tests/security_test_external_master_start.sh new file mode 100755 index 0000000..fae63a7 --- /dev/null +++ b/test/network_tests/security_tests/security_test_external_master_start.sh @@ -0,0 +1,78 @@ +#!/bin/bash +# Copyright (C) 2015-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +if [ $# -lt 2 ] +then + echo "Please pass a json file to this script and wether remote clients are allowed or not " + echo "For example: $0 security_test_config_client_external_allow.json --allow" + exit 1 +fi + +MASTER_JSON_FILE=$1 +SERVICE_JSON_FILE=${MASTER_JSON_FILE/client/service} +ALLOW_DENY=$2 + +FAIL=0 + +export VSOMEIP_CONFIGURATION=$1 +export VSOMEIP_APPLICATION_NAME=routingmanagerd +# start daemon +../../examples/routingmanagerd/./routingmanagerd & +PID_VSOMEIPD=$! + +export VSOMEIP_CONFIGURATION=$1 +export VSOMEIP_APPLICATION_NAME=client-sample +./security_test_client --remote $2 & +PID_CLIENT=$! + + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting external security test on slave LXC" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./security_test_external_slave_start.sh $SERVICE_JSON_FILE $2\"" & +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./security_test_external_slave_start.sh $SERVICE_JSON_FILE $2" & +else +cat <create_application()), + is_registered_(false), + blocked_(false), + number_of_received_messages_(0), + offer_thread_(std::bind(&security_test_service::run, this)) { +} + +bool security_test_service::init() { + std::lock_guard its_lock(mutex_); + + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, + std::bind(&security_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, + std::bind(&security_test_service::on_message_shutdown, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&security_test_service::on_state, this, + std::placeholders::_1)); + + // offer allowed field 0x8001 eventgroup 0x01 + std::set its_eventgroups; + its_eventgroups.insert(0x01); + + app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8001), its_eventgroups, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + + // also offer field 0x8002 which is not allowed to be received by client + app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8002), its_eventgroups, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + + // set value to fields + std::shared_ptr its_payload = + vsomeip::runtime::get()->create_payload(); + vsomeip::byte_t its_data[2] = {static_cast((vsomeip_test::TEST_SERVICE_SERVICE_ID & 0xFF00) >> 8), + static_cast((vsomeip_test::TEST_SERVICE_SERVICE_ID & 0xFF))}; + its_payload->set_data(its_data, 2); + + app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8001), its_payload); + + app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, + static_cast(0x8002), its_payload); + + return true; +} + +void security_test_service::start() { + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void security_test_service::stop() { + VSOMEIP_INFO << "Stopping..."; + app_->clear_all_handler(); + app_->stop(); +} + +void security_test_service::join_offer_thread() { + if (offer_thread_.joinable()) { + offer_thread_.join(); + } +} + +void security_test_service::offer() { + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); + + // try to offer a not allowed instance ID 0x02 (client requesting the service should not get available) + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, 0x02); + + // try to offer a not allowed service ID 0x111 (client requesting the service should not get available) + app_->offer_service(0x111, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void security_test_service::stop_offer() { + app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void security_test_service::on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : + "deregistered."); + + if(_state == vsomeip::state_type_e::ST_REGISTERED) { + if(!is_registered_) { + is_registered_ = true; + std::lock_guard its_lock(mutex_); + blocked_ = true; + // "start" the run method thread + condition_.notify_one(); + } + } + else { + is_registered_ = false; + } +} + +void security_test_service::on_message(const std::shared_ptr& _request) { + ASSERT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _request->get_service()); + ASSERT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _request->get_instance()); + + VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _request->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _request->get_session() << "] method: " << _request->get_method() ; + + // send response + std::shared_ptr its_response = + vsomeip::runtime::get()->create_response(_request); + + app_->send(its_response); + + number_of_received_messages_++; + if(number_of_received_messages_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS) { + VSOMEIP_INFO << "Received all messages!"; + } +} + +void security_test_service::on_message_shutdown( + const std::shared_ptr& _request) { + (void)_request; + VSOMEIP_INFO << "Shutdown method was called, going down now."; + stop(); +} + +void security_test_service::run() { + std::unique_lock its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); + + offer(); + + // do not wait for the shutdown method to be called + if (is_remote_test && !remote_client_allowed) { + std::this_thread::sleep_for(std::chrono::milliseconds(250 * vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS + 10000)); + VSOMEIP_INFO << "Shutdown the service after timeout as remote client is not allowed by policy to call shutdown method!"; + stop(); + } + +} + +TEST(someip_security_test, basic_subscribe_request_response) { + security_test_service test_service; + if (test_service.init()) { + test_service.start(); + test_service.join_offer_thread(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) { + + std::string test_remote("--remote"); + std::string test_local("--local"); + std::string test_allow_remote_client("--allow"); + std::string test_deny_remote_client("--deny"); + std::string help("--help"); + + int i = 1; + while (i < argc) + { + if(test_remote == argv[i]) + { + is_remote_test = true; + } + else if(test_local == argv[i]) + { + is_remote_test = false; + } + else if(test_allow_remote_client == argv[i]) + { + remote_client_allowed = true; + } + else if(test_deny_remote_client == argv[i]) + { + remote_client_allowed = false; + } + else if(help == argv[i]) + { + VSOMEIP_INFO << "Parameters:\n" + << "--remote: Run test between two hosts\n" + << "--local: Run test locally\n" + << "--allow: test is started with a policy that allows remote messages sent by this test client to the service\n" + << "--deny: test is started with a policy that denies remote messages sent by this test client to the service\n" + << "--help: print this help"; + } + i++; + } + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/security_tests/security_test_service.hpp b/test/network_tests/security_tests/security_test_service.hpp new file mode 100644 index 0000000..21f1f7c --- /dev/null +++ b/test/network_tests/security_tests/security_test_service.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef SECURITY_TEST_SERVICE_HPP +#define SECURITY_TEST_SERVICE_HPP + +#include + +#include + +#include "../someip_test_globals.hpp" + +#include +#include +#include + +class security_test_service { +public: + security_test_service(); + bool init(); + void start(); + void stop(); + void offer(); + void stop_offer(); + void join_offer_thread(); + void on_state(vsomeip::state_type_e _state); + void on_message(const std::shared_ptr &_request); + void on_message_shutdown(const std::shared_ptr &_request); + void run(); + +private: + std::shared_ptr app_; + bool is_registered_; + + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + std::uint32_t number_of_received_messages_; + std::thread offer_thread_; +}; + +#endif // SECURITY_TEST_SERVICE_HPP diff --git a/test/network_tests/someip_test_globals.hpp b/test/network_tests/someip_test_globals.hpp new file mode 100644 index 0000000..4380cd3 --- /dev/null +++ b/test/network_tests/someip_test_globals.hpp @@ -0,0 +1,43 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef SOMEIP_TEST_GLOBALS_HPP_ +#define SOMEIP_TEST_GLOBALS_HPP_ + +#include +#include + +namespace vsomeip_test +{ + +// Service +constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID = 0x1234; +constexpr vsomeip::instance_t TEST_SERVICE_INSTANCE_ID = 0x5678; +constexpr vsomeip::method_t TEST_SERVICE_METHOD_ID = 0x8421; +constexpr vsomeip::method_t TEST_SERVICE_METHOD_ID_SHUTDOWN = 0x7777; +constexpr vsomeip::client_t TEST_SERVICE_CLIENT_ID = 0x1277; + +// Client local +constexpr vsomeip::client_t TEST_CLIENT_CLIENT_ID = 0x1255; + +// Client external +constexpr vsomeip::client_t TEST_CLIENT_EXTERNAL_CLIENT_ID = 0x1644; + + +constexpr std::uint32_t NUMBER_OF_MESSAGES_TO_SEND = 10; +constexpr vsomeip::session_t TEST_INITIAL_SESSION_ID = 0x1; + +constexpr std::uint32_t NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS = 1000; +constexpr vsomeip::byte_t PAYLOAD_TEST_DATA = 0xDD; +constexpr std::uint32_t MAX_PAYLOADSIZE = 1024*128; +// TR_SOMEIP_00061 +constexpr std::uint32_t MAX_PAYLOADSIZE_UDP = 1400; + +constexpr std::uint32_t NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS = 32; + +constexpr std::uint32_t NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS = 32; +} + +#endif /* SOMEIP_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/someip_tp_tests/conf/someip_tp_test_master.json.in b/test/network_tests/someip_tp_tests/conf/someip_tp_test_master.json.in new file mode 100644 index 0000000..a2f67a1 --- /dev/null +++ b/test/network_tests/someip_tp_tests/conf/someip_tp_test_master.json.in @@ -0,0 +1,45 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"info", + "console":"true" + }, + "applications" : + [ + { + "name" : "someip_tp_test_service", + "id" : "0xCAFE" + } + ], + "services": + [ + { + "service":"0x4545", + "instance":"0x1", + "unreliable":"30001", + "someip-tp" : { + "service-to-client": [ "0x4545", "0x8001"] + } + }, + { + "service":"0x6767", + "instance":"0x1", + "unicast" : "@TEST_IP_SLAVE@", + "unreliable":"40001", + "someip-tp" : { + "client-to-service": [ "0x6767", "0x8001" ] + } + } + ], + "max-payload-size-unreliable" : "8352", + "routing":"routingmanagerd", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.77.1", + "port":"30490", + "protocol":"udp", + "cyclic_offer_delay" : "1000" + } +} \ No newline at end of file diff --git a/test/network_tests/someip_tp_tests/conf/someip_tp_test_master_starter.sh.in b/test/network_tests/someip_tp_tests/conf/someip_tp_test_master_starter.sh.in new file mode 100755 index 0000000..0064899 --- /dev/null +++ b/test/network_tests/someip_tp_tests/conf/someip_tp_test_master_starter.sh.in @@ -0,0 +1,65 @@ +#!/bin/bash +# Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 + +if [ $# -lt 1 ] +then + echo "Please pass a test mode to this script." + echo "For example: $0 IN_SEQUENCE" + echo "Valid subscription types include:" + echo " [IN_SEQUENCE, MIXED, INCOMPLETE, DUPLICATE, OVERLAP, OVERLAP_FRONT_BACK]" + exit 1 +fi +TESTMODE=$1 +export VSOMEIP_CONFIGURATION=someip_tp_test_master.json +# start daemon +../../examples/routingmanagerd/./routingmanagerd & +PID_VSOMEIPD=$! +# Start the services +./someip_tp_test_service $1 & +PID_SERIVCE=$! + +sleep 1 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "Waiting for 5s" + sleep 5 + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./someip_tp_test_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $TESTMODE\"" & + echo "remote ssh pid: $!" +elif [ ! -z "$USE_DOCKER" ]; then + echo "Waiting for 5s" + sleep 5 + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./someip_tp_test_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $TESTMODE" & +else +cat < + +namespace someip_tp_test { + +struct service_info { + vsomeip::service_t service_id; + vsomeip::instance_t instance_id; + vsomeip::method_t method_id; + vsomeip::event_t event_id; + vsomeip::eventgroup_t eventgroup_id; + vsomeip::method_t shutdown_method_id; + vsomeip::method_t notify_method_id; +}; + +struct service_info service = { 0x4545, 0x1, 0x4545, 0x8001, 0x1, 0x4501, 0x4502 }; +struct service_info service_slave = { 0x6767, 0x1, 0x6767, 0x8001, 0x1, 0x6701, 0x6702 }; + +enum test_mode_e { + IN_SEQUENCE, + MIXED, + INCOMPLETE, + DUPLICATE, + OVERLAP, + OVERLAP_FRONT_BACK +}; + +const std::uint32_t number_of_fragments = 6; +const std::uint32_t max_segment_size = 1392; + +} + +#endif /* SOMEIP_TP_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/someip_tp_tests/someip_tp_test_msg_sender.cpp b/test/network_tests/someip_tp_tests/someip_tp_test_msg_sender.cpp new file mode 100644 index 0000000..f2e4f9e --- /dev/null +++ b/test/network_tests/someip_tp_tests/someip_tp_test_msg_sender.cpp @@ -0,0 +1,1387 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__linux__) || defined(ANDROID) +#include +#endif + +#include + +#include + +#include + +#include "../../implementation/utility/include/byteorder.hpp" +#include "../../implementation/message/include/deserializer.hpp" +#include "../../implementation/message/include/serializer.hpp" +#include "../../implementation/service_discovery/include/service_discovery.hpp" +#include "../../implementation/service_discovery/include/message_impl.hpp" +#include "../../implementation/service_discovery/include/constants.hpp" +#include "../../implementation/service_discovery/include/enumeration_types.hpp" +#include "../../implementation/service_discovery/include/eventgroupentry_impl.hpp" +#include "../../implementation/service_discovery/include/serviceentry_impl.hpp" +#include "../../implementation/message/include/message_impl.hpp" +#include "../../implementation/service_discovery/include/option_impl.hpp" +#include "../../implementation/service_discovery/include/ipv4_option_impl.hpp" +#include "../../implementation/endpoints/include/tp.hpp" +#include "../../implementation/endpoints/include/tp_reassembler.hpp" +#include "../../implementation/message/include/payload_impl.hpp" + +#include "someip_tp_test_globals.hpp" + +static char* remote_address; +static char* local_address; + +std::vector its_modes({ + someip_tp_test::test_mode_e::IN_SEQUENCE, + someip_tp_test::test_mode_e::MIXED, + someip_tp_test::test_mode_e::INCOMPLETE, + someip_tp_test::test_mode_e::DUPLICATE, + someip_tp_test::test_mode_e::OVERLAP, + someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK, +}); + +class someip_tp : public ::testing::TestWithParam { +public: + someip_tp() : + work_(std::make_shared(io_)), + io_thread_(std::bind(&someip_tp::io_run, this)), + session_(0x0), + sd_session_(0x0), + address_remote_(boost::asio::ip::address::from_string(std::string(remote_address))), + address_local_(boost::asio::ip::address::from_string(std::string(local_address))), + runtime_(vsomeip::runtime::get()) {} +protected: + void TearDown() { + work_.reset(); + io_thread_.join(); + io_.stop(); + } + + void call_shutdown_method() { + boost::system::error_code ec; + std::uint8_t shutdown_call[] = { + 0x45, 0x45, 0x45, 0x01, + 0x00, 0x00, 0x00, 0x08, + 0xDD, 0xDD, 0x00, 0x01, + 0x01, 0x00, 0x00, 0x00 }; + boost::asio::ip::udp::socket::endpoint_type target_service(address_remote_, + 30001); + boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); + udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); + udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_socket2.close(ec); + } + + void io_run() { + io_.run(); + } + + void offer_service(boost::asio::ip::udp::socket* const _udp_socket) { + // offer the service + std::uint8_t its_offer_service_message[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x01, 0x00, 0x00, 0x20, + 0x67, 0x67, 0x00, 0x01, // service / instance + 0x00, 0xff, 0xff, 0xff, // major / ttl + 0x00, 0x00, 0x00, 0x00, // minor + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // slave address + 0x00, 0x11, 0x9c, 0x41, + }; + std::memcpy(&its_offer_service_message[48], &address_local_.to_v4().to_bytes()[0], 4); + std::uint16_t its_session = htons(++sd_session_); + std::memcpy(&its_offer_service_message[10], &its_session, sizeof(its_session)); + + boost::asio::ip::udp::socket::endpoint_type target_sd(address_remote_,30490); + _udp_socket->send_to(boost::asio::buffer(its_offer_service_message), target_sd); + } + + void subscribe_at_master(boost::asio::ip::udp::socket* const _udp_socket) { + std::uint8_t its_subscription[] = { + 0xff, 0xff, 0x81, 0x00, + 0x00, 0x00, 0x00, 0x30, // length + 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x00, + 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, // length entries array + 0x06, 0x00, 0x00, 0x10, + 0x45, 0x45, 0x00, 0x01, // service / instance + 0x00, 0xff, 0xff, 0xff, // major / ttl + 0x00, 0x00, 0x00, 0x01, // counter + 0x00, 0x00, 0x00, 0x0c, // length options array + 0x00, 0x09, 0x04, 0x00, + 0xff, 0xff, 0xff, 0xff, // slave address + 0x00, 0x11, 0x75, 0x31, // port 30001 + }; + std::memcpy(&its_subscription[48], &address_local_.to_v4().to_bytes()[0], 4); + std::uint16_t its_session = htons(++sd_session_); + std::memcpy(&its_subscription[10], &its_session, sizeof(its_session)); + + boost::asio::ip::udp::socket::endpoint_type target_sd(address_remote_,30490); + _udp_socket->send_to(boost::asio::buffer(its_subscription), target_sd); + } + + /* + * @brief custom version of tp::tp_split_message with adjustable segment size + * needed to send overlapping segments within the 1392 byte segment size limit + */ + vsomeip::tp::tp_split_messages_t split_message(const std::uint8_t * const _data, + std::uint32_t _size , std::uint32_t _segment_size) { + using namespace vsomeip::tp; + using namespace vsomeip; + tp_split_messages_t split_messages; + + if (_size < VSOMEIP_MAX_UDP_MESSAGE_SIZE) { + std::cerr << __func__ << " called with size: " << std::dec << _size; + return split_messages; + } + + const auto data_end = _data + _size; + + for (auto current_offset = _data + 16; current_offset < data_end;) { + auto msg = std::make_shared(); + msg->reserve(VSOMEIP_FULL_HEADER_SIZE + sizeof(tp_header_t) + _segment_size); + // copy the header + msg->insert(msg->end(), _data, _data + VSOMEIP_FULL_HEADER_SIZE); + // change the message type + (*msg)[VSOMEIP_MESSAGE_TYPE_POS] = (*msg)[VSOMEIP_MESSAGE_TYPE_POS] | 0x20; + // check if last segment + const auto segment_end = current_offset + _segment_size; + const bool is_last_segment = (segment_end >= data_end); + // insert tp_header + const tp_header_t header = htonl( + static_cast((current_offset - VSOMEIP_FULL_HEADER_SIZE - _data)) | + static_cast((is_last_segment) ? 0x0u : 0x1u)); + + const byte_t * const headerp = reinterpret_cast(&header); + msg->insert(msg->end(), headerp, headerp + sizeof(tp_header_t)); + + // insert payload + if (is_last_segment) { + msg->insert(msg->end(), current_offset, data_end); + current_offset = data_end; + } else { + msg->insert(msg->end(), current_offset, segment_end); + current_offset += _segment_size; + } + // update length + const length_t its_length = static_cast(msg->size() + - VSOMEIP_SOMEIP_HEADER_SIZE); + *(reinterpret_cast(&(*msg)[VSOMEIP_LENGTH_POS_MIN])) = htonl(its_length); + split_messages.emplace_back(std::move(msg)); + } + + return split_messages; + } + + void create_fragments(std::uint32_t _count, vsomeip::service_t _service, + vsomeip::instance_t _instance, + vsomeip::method_t _method, + vsomeip::message_type_e _message_type, + vsomeip::client_t _client, + vsomeip::session_t _session, + std::vector* _target, + std::uint32_t _segment_size) { + vsomeip::message_impl msg; + msg.set_reliable(false); + msg.set_service(_service); + msg.set_instance(_instance); + msg.set_method(_method); + msg.set_message_type(_message_type); + msg.set_return_code(vsomeip::return_code_e::E_OK); + if (_client == vsomeip::ANY_CLIENT) { + msg.set_client(0xDDDD); + } else { + msg.set_client(_client); + } + if (_session == 0xFFFF) { + msg.set_session(++session_); + } else { + msg.set_session(_session); + } + std::vector its_payload_data; + for (uint32_t i = 0; i < _count; i++) { + its_payload_data.resize((i * _segment_size) + _segment_size, static_cast(i)); + } + std::shared_ptr payload = std::make_shared(its_payload_data); + msg.set_payload(payload); + vsomeip::serializer its_serializer(0); + msg.serialize(&its_serializer); + + *_target = split_message(its_serializer.get_data(), its_serializer.get_size(), _segment_size); + its_serializer.reset(); + + } + + vsomeip::message_buffer_t create_full_message( + const std::vector& _fragments) { + auto its_reassembler = std::make_shared( + std::numeric_limits::max(), io_); + vsomeip::message_buffer_t its_reassemlbed_msg; + for (const auto& frag : _fragments) { + const auto res = its_reassembler->process_tp_message(&(*frag)[0], + std::uint32_t(frag->size()), address_local_, 12345); + if (res.first) { + its_reassemlbed_msg = res.second; + } + } + its_reassembler->stop(); + return its_reassemlbed_msg; + } + + std::vector create_shuffled_seqeuence(std::uint32_t _count) { + std::vector its_indexes(_count); + std::iota(its_indexes.begin(), its_indexes.end(), 0); + std::random_device rd; + std::mt19937 its_twister(rd()); + std::shuffle(its_indexes.begin(), its_indexes.end(), its_twister); + return its_indexes; + } + void increase_segment_back(const vsomeip::message_buffer_ptr_t& _seg, + std::uint32_t _amount) { + _seg->resize(_seg->size() + _amount, 0xff); + // update length + *(reinterpret_cast(&((*_seg)[VSOMEIP_LENGTH_POS_MIN]))) = + htonl(static_cast(_seg->size() - VSOMEIP_SOMEIP_HEADER_SIZE)); + } + + void increase_segment_front(const vsomeip::message_buffer_ptr_t& _seg, + std::uint32_t _amount) { + // increase segment by amount + _seg->insert(_seg->begin() + VSOMEIP_TP_PAYLOAD_POS, _amount, 0xff); + + // decrease offset by amount + const vsomeip::tp::tp_header_t its_tp_header = VSOMEIP_BYTES_TO_LONG( + (*_seg)[VSOMEIP_TP_HEADER_POS_MIN], + (*_seg)[VSOMEIP_TP_HEADER_POS_MIN + 1], + (*_seg)[VSOMEIP_TP_HEADER_POS_MIN + 2], + (*_seg)[VSOMEIP_TP_HEADER_POS_MAX]); + std::uint32_t its_offset = vsomeip::tp::tp::get_offset(its_tp_header); + its_offset -= _amount; + const vsomeip::tp::tp_header_t its_new_tp_header = + htonl(static_cast(its_offset | + static_cast(its_tp_header & 0x1))); + *(reinterpret_cast( + &((*_seg)[VSOMEIP_TP_HEADER_POS_MIN]))) = its_new_tp_header; + + // update length + *(reinterpret_cast(&((*_seg)[VSOMEIP_LENGTH_POS_MIN]))) = + htonl(static_cast(_seg->size() - VSOMEIP_SOMEIP_HEADER_SIZE)); + } + + void increase_segment_front_back(const vsomeip::message_buffer_ptr_t& _seg, + std::uint32_t _amount) { + increase_segment_front(_seg, _amount); + increase_segment_back(_seg, _amount); + } + + void decrease_segment_back(const vsomeip::message_buffer_ptr_t& _seg, + std::uint32_t _amount) { + _seg->resize(_seg->size() - _amount, 0xff); + // update length + *(reinterpret_cast(&((*_seg)[VSOMEIP_LENGTH_POS_MIN]))) = + htonl(static_cast(_seg->size() - VSOMEIP_SOMEIP_HEADER_SIZE)); + } + + void decrease_segment_front(const vsomeip::message_buffer_ptr_t& _seg, + std::uint32_t _amount) { + if (_amount % 16 != 0) { + std::cerr << __func__ << ":" << __LINE__ << std::endl; + return; + } + _seg->erase(_seg->begin() + VSOMEIP_TP_PAYLOAD_POS, _seg->begin() + VSOMEIP_TP_PAYLOAD_POS + _amount); + // increase offset by amount + const vsomeip::tp::tp_header_t its_tp_header = VSOMEIP_BYTES_TO_LONG( + (*_seg)[VSOMEIP_TP_HEADER_POS_MIN], + (*_seg)[VSOMEIP_TP_HEADER_POS_MIN + 1], + (*_seg)[VSOMEIP_TP_HEADER_POS_MIN + 2], + (*_seg)[VSOMEIP_TP_HEADER_POS_MAX]); + std::uint32_t its_offset = vsomeip::tp::tp::get_offset(its_tp_header); + its_offset += _amount; + const vsomeip::tp::tp_header_t its_new_tp_header = + htonl(static_cast(its_offset | + static_cast(its_tp_header & 0x1))); + *(reinterpret_cast( + &((*_seg)[VSOMEIP_TP_HEADER_POS_MIN]))) = its_new_tp_header; + // update length + *(reinterpret_cast(&((*_seg)[VSOMEIP_LENGTH_POS_MIN]))) = + htonl(static_cast(_seg->size() - VSOMEIP_SOMEIP_HEADER_SIZE)); + } + + void decrease_segment_front_back(const vsomeip::message_buffer_ptr_t& _seg, + std::uint32_t _amount) { + if (_amount % 16 != 0) { + std::cerr << __func__ << ":" << __LINE__ << std::endl; + return; + } + decrease_segment_back(_seg, _amount); + decrease_segment_front(_seg, _amount); + } + + + enum order_e { + ASCENDING, + DESCENDING, + MIXED_PREDEFINED, + MIXED_RANDOM, + }; + + boost::asio::io_context io_; + std::shared_ptr work_; + std::thread io_thread_; + std::vector fragments_request_to_master_; + std::vector fragments_response_of_master_; + + std::vector fragments_received_as_server_; + std::vector fragments_response_to_master_; + + std::vector fragments_event_from_master_; + std::vector fragments_event_to_master_; + + std::atomic session_; + std::atomic sd_session_; + boost::asio::ip::address address_remote_; + boost::asio::ip::address address_local_; + std::shared_ptr runtime_; + someip_tp_test::test_mode_e test_mode_ = GetParam(); +}; + +INSTANTIATE_TEST_CASE_P(send_in_mode, + someip_tp, + ::testing::ValuesIn(its_modes)); + + +/* + * @test Send a big fragmented UDP request to the master and wait for the + * response. Check that the received response is the same as the request (server + * just echos the requests). + * Wait for a big fragmented UDP message request from the master and send back + * the response in the same size. Check that the request and response are + * identical. + * Do this two times one with fragments ordered ascending and one time descending. + * Wait for the master to subscribe and send back two big, fragmented + * notifications one with fragments ordered ascending and one descending + * Subscribe at master and wait for one fragmented event. + * With testmode INCOMPLETE incomplete fragments are send as well + * With testmode MIXED instead of ascending/descedning order the fragments are + * send in a predefined or in a random order + */ +TEST_P(someip_tp, send_in_mode) +{ + std::promise remote_client_subscribed; + std::atomic remote_client_subscription_port(0); + std::promise offer_received; + + std::mutex udp_sd_socket_mutex; + boost::asio::ip::udp::socket udp_sd_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); + + boost::asio::ip::udp::socket udp_client_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30001)); + + boost::asio::ip::udp::socket udp_server_socket(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 40001)); + + std::thread sd_receive_thread([&](){ + std::atomic keep_receiving(true); + std::vector receive_buffer(4096); + std::vector its_received_events; + std::atomic service_offered(false); + std::atomic client_subscribed(false); + + // join the sd multicast group 224.0.77.1 + udp_sd_socket.set_option(boost::asio::ip::multicast::join_group( + boost::asio::ip::address::from_string("224.0.77.1").to_v4())); + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_sd_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + return; + } else { + vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], + receive_buffer[VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], + receive_buffer[VSOMEIP_METHOD_POS_MAX]); + if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { + vsomeip::sd::message_impl sd_msg; + EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); + EXPECT_EQ(1u, sd_msg.get_entries().size()); + for (const auto& e : sd_msg.get_entries()) { + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { + EXPECT_TRUE(e->is_eventgroup_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); + EXPECT_EQ(1,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(someip_tp_test::service_slave.service_id, e->get_service()); + EXPECT_EQ(someip_tp_test::service_slave.instance_id, e->get_instance()); + EXPECT_EQ(1u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_EQ(someip_tp_test::service_slave.eventgroup_id, + its_casted_entry->get_eventgroup()); + std::shared_ptr its_option = + sd_msg.get_options().at(its_casted_entry->get_options(1)[0]); + EXPECT_TRUE(its_option > 0); + if(its_option->get_type() == vsomeip::sd::option_type_e::IP4_ENDPOINT) { + std::shared_ptr its_ipv4_option = + std::dynamic_pointer_cast (its_option); + EXPECT_TRUE(its_ipv4_option > 0); + EXPECT_EQ(vsomeip::sd::layer_four_protocol_e::UDP, its_ipv4_option->get_layer_four_protocol()); + EXPECT_EQ(address_remote_, + boost::asio::ip::address( + boost::asio::ip::address_v4(its_ipv4_option->get_address()))); + remote_client_subscription_port = its_ipv4_option->get_port(); + } + std::vector its_sub_ack(&receive_buffer[0], &receive_buffer[0] + VSOMEIP_FULL_HEADER_SIZE + 8 + (sd_msg.get_entries().size() * 16)); + its_sub_ack[24] = static_cast(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK); + // fix length + const std::uint32_t its_length = htonl(static_cast(its_sub_ack.size()) - VSOMEIP_SOMEIP_HEADER_SIZE); + std::memcpy(&its_sub_ack[4], &its_length, sizeof(its_length)); + // set number of options to zero + its_sub_ack[27] = 0x0; + // update session + std::uint16_t its_session = htons(++sd_session_); + std::memcpy(&its_sub_ack[10], &its_session, sizeof(its_session)); + boost::asio::ip::udp::socket::endpoint_type target_sd(address_remote_,30490); + { + std::lock_guard its_lock(udp_sd_socket_mutex); + udp_sd_socket.send_to(boost::asio::buffer(its_sub_ack), target_sd); + } + std::cout << __LINE__ << ": master subscribed" << std::endl; + remote_client_subscribed.set_value(); + client_subscribed = true; + } + } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { + EXPECT_TRUE(e->is_service_entry()); + EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); + EXPECT_EQ(1u,e->get_num_options(1)); + EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); + EXPECT_EQ(someip_tp_test::service.service_id, e->get_service()); + EXPECT_EQ(someip_tp_test::service.instance_id, e->get_instance()); + EXPECT_EQ(1u, sd_msg.get_options().size()); + if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { + std::shared_ptr its_casted_entry = + std::static_pointer_cast(e); + EXPECT_EQ(0u, its_casted_entry->get_minor_version()); + } + offer_received.set_value(); + service_offered = true; + } + } + if (service_offered && client_subscribed) { + keep_receiving = false; + } + } else { + ADD_FAILURE() << " received non-sd message"; + return; + } + } + } + }); + + std::thread send_thread([&]() { + boost::system::error_code ec; + try { + + // wait until a offer was received + if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Didn't receive offer within time"; + return; + } + + { + std::lock_guard its_lock(udp_sd_socket_mutex); + subscribe_at_master(&udp_sd_socket); + } + + std::mutex all_fragments_received_mutex_; + std::condition_variable all_fragments_received_cond_; + bool wait_for_all_response_fragments_received_(true); + std::uint32_t received_responses(0); + bool wait_for_all_event_fragments_received_(true); + + std::thread udp_client_receive_thread([&]() { + bool keep_receiving(true); + std::vector receive_buffer(4096); + while (keep_receiving) { + boost::system::error_code error; + std::size_t bytes_transferred = udp_client_socket.receive( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + return; + } else { + std::uint32_t its_pos = 0; + + while (bytes_transferred > 0) { + const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + std::cout << __LINE__ << ": received response " << its_message_size << std::endl; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], + receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], + receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); + + vsomeip::message_impl msg; + EXPECT_TRUE(msg.deserialize(&its_deserializer)); + if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); + EXPECT_EQ(someip_tp_test::service.service_id, msg.get_service()); + } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + std::cout << __LINE__ << ": received event" << std::endl; + } else if (vsomeip::tp::tp::tp_flag_is_set(receive_buffer[its_pos + VSOMEIP_MESSAGE_TYPE_POS]) && + vsomeip::tp::tp::tp_flag_unset(receive_buffer[its_pos + VSOMEIP_MESSAGE_TYPE_POS]) == vsomeip::message_type_e::MT_RESPONSE) { + EXPECT_EQ(someip_tp_test::service.service_id, its_service); + EXPECT_EQ(someip_tp_test::service.method_id, its_method); + auto its_buffer = std::make_shared(&receive_buffer[its_pos], &receive_buffer[its_pos] + its_message_size); + + fragments_response_of_master_.push_back(its_buffer); + if (fragments_response_of_master_.size() == someip_tp_test::number_of_fragments) { + std::lock_guard its_lock(all_fragments_received_mutex_); + wait_for_all_response_fragments_received_ = false; + std::cout << __LINE__ << ": received all response fragments as client" << std::endl; + all_fragments_received_cond_.notify_one(); + if (++received_responses == 2 && !wait_for_all_event_fragments_received_) { + std::cout << __LINE__ << ": received all responses as client --> Finished" << std::endl; + keep_receiving = false; + } + } + } else if (vsomeip::tp::tp::tp_flag_is_set(receive_buffer[its_pos + VSOMEIP_MESSAGE_TYPE_POS]) && + vsomeip::tp::tp::tp_flag_unset(receive_buffer[its_pos + VSOMEIP_MESSAGE_TYPE_POS]) == vsomeip::message_type_e::MT_NOTIFICATION) { + std::cout << __LINE__ << ": received event fragment" << std::endl; + EXPECT_EQ(someip_tp_test::service.service_id, its_service); + EXPECT_EQ(someip_tp_test::service.event_id, its_method); + auto its_buffer = std::make_shared(&receive_buffer[its_pos], &receive_buffer[its_pos] + its_message_size); + fragments_event_from_master_.push_back(its_buffer); + if (fragments_event_from_master_.size() == someip_tp_test::number_of_fragments) { + std::lock_guard its_lock(all_fragments_received_mutex_); + wait_for_all_event_fragments_received_ = false; + std::cout << __LINE__ << ": received all event fragments as client --> Finished" << std::endl; + all_fragments_received_cond_.notify_one(); + if (received_responses == 2) { + keep_receiving = false; + } + } + + } + its_pos += its_message_size; + bytes_transferred -= its_message_size; + } + } + } + }); + + // send SOMEI-TP message fragmented into 6 parts to service: + boost::asio::ip::udp::socket::endpoint_type target_service(address_remote_, 30001); + + std::unique_lock its_lock(all_fragments_received_mutex_); + for (const order_e mode : {order_e::ASCENDING, order_e::DESCENDING}) { + create_fragments(someip_tp_test::number_of_fragments, someip_tp_test::service.service_id, + someip_tp_test::service.instance_id, + someip_tp_test::service.method_id, + vsomeip::message_type_e::MT_REQUEST, + vsomeip::ANY_CLIENT, 0xffff, + &fragments_request_to_master_, + (test_mode_ == someip_tp_test::test_mode_e::OVERLAP || + test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) ? + vsomeip::tp::tp::tp_max_segment_length_ - 160 : + vsomeip::tp::tp::tp_max_segment_length_); + if (mode == order_e::ASCENDING) { + if (test_mode_ == someip_tp_test::test_mode_e::MIXED) { + if (someip_tp_test::number_of_fragments != 6) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } else { + auto its_indexes = {4, 1, 3, 5, 2, 0}; + std::cout << __LINE__ << ": using following predefined sequence to send request to master: "; + for (auto i : its_indexes) { std::cout << i << ", "; } + std::cout << std::endl; + for (int i : its_indexes) { + udp_client_socket.send_to(boost::asio::buffer(*fragments_request_to_master_[i]), target_service); + } + } + } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { + if (someip_tp_test::number_of_fragments != 6) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + } else { + auto its_indexes = {0,1,3,5,2,4}; + std::cout << __LINE__ << ": using following predefined sequence to send request to master: "; + for (auto i : its_indexes) { std::cout << i << ", "; } + std::cout << std::endl; + // increase third segment by 16 byte at front and back + increase_segment_front_back(fragments_request_to_master_[2], 16); + increase_segment_front(fragments_request_to_master_[4], 16); + for (int i : its_indexes) { + udp_client_socket.send_to(boost::asio::buffer(*fragments_request_to_master_[i]), target_service); + } + } + } else if (test_mode_ == someip_tp_test::test_mode_e::DUPLICATE) { + if (someip_tp_test::number_of_fragments < 2) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + for (auto iter = fragments_request_to_master_.begin(); + iter != fragments_request_to_master_.end(); iter++) { + udp_client_socket.send_to(boost::asio::buffer(*(*iter)), target_service); + // send insert 2nd fragment twice + if (iter == fragments_request_to_master_.begin() + 1) { + udp_client_socket.send_to(boost::asio::buffer(*(*iter)), target_service); + } + } + } else { + if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { + if (someip_tp_test::number_of_fragments < 3) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + // send a request fragment with a different session ID first + vsomeip::message_buffer_t msg_incomplete(*fragments_request_to_master_[2]); + msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0x33; + msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0x33; + udp_client_socket.send_to(boost::asio::buffer(msg_incomplete), target_service); + // send a request from a different src port as well to test cleanup + boost::asio::ip::udp::socket udp_client_socket2(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30004)); + msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0xcc; + msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0xcc; + udp_client_socket2.send_to(boost::asio::buffer(msg_incomplete), target_service); + boost::system::error_code ec; + udp_client_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_client_socket2.close(ec); + } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { + if (someip_tp_test::number_of_fragments < 2) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + increase_segment_back(fragments_request_to_master_[1], 16); + } + for (const auto& fragment : fragments_request_to_master_) { + udp_client_socket.send_to(boost::asio::buffer(*fragment), target_service); + } + } + } else if (mode == order_e::DESCENDING) { + if (test_mode_ == someip_tp_test::test_mode_e::MIXED) { + std::vector its_indexes = create_shuffled_seqeuence(someip_tp_test::number_of_fragments); + std::cout << __LINE__ << ": using following random sequence to send request to master: "; + for (auto i : its_indexes) { std::cout << i << ", "; } + std::cout << std::endl; + for (int i : its_indexes) { + udp_client_socket.send_to(boost::asio::buffer(*fragments_request_to_master_[i]), target_service); + } + } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { + if (someip_tp_test::number_of_fragments != 6) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + } else { + auto its_indexes = {5,3,2,4,1,0}; + std::cout << __LINE__ << ": using following predefined sequence to send request to master: "; + for (auto i : its_indexes) { std::cout << i << ", "; } + std::cout << std::endl; + // increase third segment by 16 byte at front and back + increase_segment_front_back(fragments_request_to_master_[4], 16); + for (int i : its_indexes) { + udp_client_socket.send_to(boost::asio::buffer(*fragments_request_to_master_[i]), target_service); + } + } + } else if (test_mode_ == someip_tp_test::test_mode_e::DUPLICATE) { + if (someip_tp_test::number_of_fragments < 2) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + for (auto iter = fragments_request_to_master_.rbegin(); + iter != fragments_request_to_master_.rend(); iter++) { + udp_client_socket.send_to(boost::asio::buffer(*(*iter)), target_service); + // send insert 2nd last fragment twice + if (iter == fragments_request_to_master_.rbegin() + 1) { + udp_client_socket.send_to(boost::asio::buffer(*(*iter)), target_service); + } + } + } else { + if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { + if (someip_tp_test::number_of_fragments < 4) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + // send a request fragment with a different session ID first + vsomeip::message_buffer_t msg_incomplete(*fragments_request_to_master_[3]); + msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0x77; + msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0x77; + udp_client_socket.send_to(boost::asio::buffer(msg_incomplete), target_service); + + // send a request from a different src port as well to test cleanup + boost::asio::ip::udp::socket udp_client_socket2(io_, + boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30005)); + msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0xdd; + msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0xdd; + udp_client_socket2.send_to(boost::asio::buffer(msg_incomplete), target_service); + boost::system::error_code ec; + udp_client_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_client_socket2.close(ec); + } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { + if (someip_tp_test::number_of_fragments < 5) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + // increase second last segment by 16 byte + increase_segment_back(fragments_request_to_master_[4], 16); + } + for (auto iter = fragments_request_to_master_.rbegin(); iter != fragments_request_to_master_.rend(); iter++) { + udp_client_socket.send_to(boost::asio::buffer(*(*iter)), target_service); + } + } + } + { + while (wait_for_all_response_fragments_received_) { + if (std::cv_status::timeout == + all_fragments_received_cond_.wait_for(its_lock, + std::chrono::seconds(20))) { + ADD_FAILURE() << "Didn't receive response to" + " fragmented message within time: " << std::uint32_t(mode); + return; + } else { + EXPECT_EQ(someip_tp_test::number_of_fragments, fragments_request_to_master_.size()); + // create complete message from request + if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { + if (mode == ASCENDING) { + if (someip_tp_test::number_of_fragments < 2) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + // decrease second segment by 16 byte + decrease_segment_back(fragments_request_to_master_[1], 16); + } else if (mode == DESCENDING) { + if (someip_tp_test::number_of_fragments < 5) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + // decrease fourth segment by 16 byte + decrease_segment_back(fragments_request_to_master_[4], 16); + } + } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { + // remove the additional inserted bytes which weren't accepted on + // test masterside as they were overlapping + if (mode == ASCENDING) { + decrease_segment_front_back(fragments_request_to_master_[2], 16); + decrease_segment_front(fragments_request_to_master_[4], 16); + } else { + decrease_segment_front_back(fragments_request_to_master_[4], 16); + } + } + vsomeip::message_buffer_t its_request = create_full_message(fragments_request_to_master_); + if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP || + test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { + EXPECT_EQ(VSOMEIP_FULL_HEADER_SIZE + + someip_tp_test::number_of_fragments * (someip_tp_test::max_segment_size - 160), + its_request.size()); + } else { + EXPECT_EQ(VSOMEIP_FULL_HEADER_SIZE + + someip_tp_test::number_of_fragments * someip_tp_test::max_segment_size, + its_request.size()); + } + if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP && mode == ASCENDING) { + // response contains the additional 16 bytes of 2nd fragment instead + // of beginning of the 3rd fragment + for (std::uint32_t i = 0; i < 16; i++) { + its_request[VSOMEIP_PAYLOAD_POS + 2 * (someip_tp_test::max_segment_size - 160) + i] = 0xff; + } + } + + // create complete message from response + vsomeip::message_buffer_t its_response = create_full_message(fragments_response_of_master_); + if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP || + test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { + EXPECT_EQ(VSOMEIP_FULL_HEADER_SIZE + + someip_tp_test::number_of_fragments * (someip_tp_test::max_segment_size - 160), + its_response.size()); + } else { + EXPECT_EQ(VSOMEIP_FULL_HEADER_SIZE + + someip_tp_test::number_of_fragments * someip_tp_test::max_segment_size, + its_response.size()); + } + // change message type of response to request again + its_response[VSOMEIP_MESSAGE_TYPE_POS] = static_cast(vsomeip::message_type_e::MT_REQUEST); + // request and response should now be equal + EXPECT_EQ(its_response.size(), its_request.size()); + EXPECT_EQ(its_response, its_request); + EXPECT_EQ(0, std::memcmp(static_cast(&its_response[0]), + static_cast(&its_request[0]), + its_response.size())); + fragments_response_of_master_.clear(); + } + } + wait_for_all_response_fragments_received_ = true; + } + fragments_request_to_master_.clear(); + } + + while (wait_for_all_event_fragments_received_) { + if (std::cv_status::timeout == + all_fragments_received_cond_.wait_for(its_lock, + std::chrono::seconds(20))) { + ADD_FAILURE() << "Didn't receive fragmented event from " + " master within time"; + } + } + // check if received event is correct + { + EXPECT_EQ(someip_tp_test::number_of_fragments, fragments_event_from_master_.size()); + // create complete message from event + vsomeip::message_buffer_t its_event = create_full_message(fragments_event_from_master_); + vsomeip::session_t its_event_session = + VSOMEIP_BYTES_TO_WORD(its_event[VSOMEIP_SESSION_POS_MIN], + its_event[VSOMEIP_SESSION_POS_MAX]); + + std::vector its_cmp_event_fragments; + create_fragments(someip_tp_test::number_of_fragments, + someip_tp_test::service.service_id, + someip_tp_test::service.instance_id, + someip_tp_test::service.event_id, + vsomeip::message_type_e::MT_NOTIFICATION, + 0x0, its_event_session, &its_cmp_event_fragments, + (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) ? + vsomeip::tp::tp::tp_max_segment_length_ - 160 : + vsomeip::tp::tp::tp_max_segment_length_); + vsomeip::message_buffer_t its_cmp_event = create_full_message(its_cmp_event_fragments); + EXPECT_EQ(its_cmp_event.size(), its_event.size()); + EXPECT_EQ(its_cmp_event, its_event); + EXPECT_EQ(0, std::memcmp(static_cast(&its_cmp_event[0]), + static_cast(&its_event[0]), + its_cmp_event.size())); + } + its_lock.unlock(); + udp_client_receive_thread.join(); + } catch (const std::exception& _e) { + ADD_FAILURE() << "catched exception: " << _e.what(); + } + }); + + std::mutex all_fragments_received_as_server_mutex_; + std::unique_lock all_fragments_received_as_server_lock(all_fragments_received_as_server_mutex_); + std::condition_variable all_fragments_received_as_server_cond_; + bool wait_for_all_fragments_received_as_server_(true); + std::atomic remote_client_request_port(0); + + std::thread udp_server_send_thread([&]() { + // wait until client subscribed + if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { + ADD_FAILURE() << "Client didn't subscribe within time"; + return; + } + + // send fragmented event to the master + boost::asio::ip::udp::socket::endpoint_type master_client(address_remote_, remote_client_subscription_port); + for (const order_e mode : {order_e::ASCENDING, order_e::DESCENDING}) { + create_fragments(someip_tp_test::number_of_fragments, + someip_tp_test::service_slave.service_id, + someip_tp_test::service_slave.instance_id, + someip_tp_test::service_slave.event_id, + vsomeip::message_type_e::MT_NOTIFICATION, + vsomeip::ANY_CLIENT, 0xffff, + &fragments_event_to_master_, + (test_mode_ == someip_tp_test::test_mode_e::OVERLAP || + test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) ? + vsomeip::tp::tp::tp_max_segment_length_ - 160 : + vsomeip::tp::tp::tp_max_segment_length_); + if (mode == order_e::ASCENDING) { + if (test_mode_ == someip_tp_test::test_mode_e::MIXED) { + if (someip_tp_test::number_of_fragments != 6) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + } else { + auto its_indexes = {2, 3, 5, 1, 4, 0}; + std::cout << __LINE__ << ": using following predefined sequence to send event to master: "; + for (auto i : its_indexes) { std::cout << i << ", "; } + std::cout << std::endl; + for (int i : its_indexes) { + udp_server_socket.send_to(boost::asio::buffer(*fragments_event_to_master_[i]), master_client); + } + } + } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { + if (someip_tp_test::number_of_fragments != 6) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + } else { + auto its_indexes = {0,2,4,5,1,3}; + std::cout << __LINE__ << ": using following predefined sequence to send event to master: "; + for (auto i : its_indexes) { std::cout << i << ", "; } + std::cout << std::endl; + // increase second segment by 16 byte at front and back + increase_segment_front_back(fragments_event_to_master_[1], 16); + increase_segment_front(fragments_event_to_master_[3], 16); + + for (int i : its_indexes) { + udp_server_socket.send_to(boost::asio::buffer(*fragments_event_to_master_[i]), master_client); + } + } + } else if (test_mode_ == someip_tp_test::test_mode_e::DUPLICATE) { + if (someip_tp_test::number_of_fragments < 2) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + for (auto iter = fragments_event_to_master_.begin(); + iter != fragments_event_to_master_.end(); iter++) { + udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); + // send insert 2nd fragment twice + if (iter == fragments_event_to_master_.begin() + 1) { + udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); + // send oversized fragment as well + increase_segment_back(*iter, 4); + udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); + decrease_segment_back(*iter, 4); + } + } + } else { + if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { + if (someip_tp_test::number_of_fragments < 3) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + // send an event fragment with a different session ID first + vsomeip::message_buffer_t msg_incomplete(*fragments_event_to_master_[2]); + msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0x44; + msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0x44; + udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); + // send a request with a different service ID as well to test cleanup + msg_incomplete[VSOMEIP_SERVICE_POS_MIN] = 0xdd; + msg_incomplete[VSOMEIP_SERVICE_POS_MAX] = 0xdd; + msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0xdd; + msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0xdd; + udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); + } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { + if (someip_tp_test::number_of_fragments < 2) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + // increase second segment by 16 byte + increase_segment_back(fragments_event_to_master_[1], 16); + + // send one oversize message as well + std::vector oversized_event; + create_fragments(someip_tp_test::number_of_fragments + 1, + someip_tp_test::service_slave.service_id, + someip_tp_test::service_slave.instance_id, + someip_tp_test::service_slave.event_id, + vsomeip::message_type_e::MT_NOTIFICATION, + vsomeip::ANY_CLIENT, 0xffff, + &oversized_event, + vsomeip::tp::tp::tp_max_segment_length_); + for (const auto& fragment : oversized_event) { + udp_server_socket.send_to(boost::asio::buffer(*fragment), master_client); + } + } + for (const auto& fragment : fragments_event_to_master_) { + udp_server_socket.send_to(boost::asio::buffer(*fragment), master_client); + } + } + } else if (mode == order_e::DESCENDING) { + if (test_mode_ == someip_tp_test::test_mode_e::MIXED) { + std::vector its_indexes = create_shuffled_seqeuence(someip_tp_test::number_of_fragments); + std::cout << __LINE__ << ": using following random sequence to send event to master: "; + for (auto i : its_indexes) { std::cout << i << ", "; } + std::cout << std::endl; + for ( int i : its_indexes) { + udp_server_socket.send_to(boost::asio::buffer(*fragments_event_to_master_[i]), master_client); + } + } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { + if (someip_tp_test::number_of_fragments != 6) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + } else { + auto its_indexes = {5,3,2,1,0,4}; + std::cout << __LINE__ << ": using following predefined sequence to send event to master: "; + for (auto i : its_indexes) { std::cout << i << ", "; } + std::cout << std::endl; + // increase second last segment by 16 byte at front and back + increase_segment_front_back(fragments_event_to_master_[4], 16); + // update length + *(reinterpret_cast(&((*fragments_event_to_master_[4])[VSOMEIP_LENGTH_POS_MIN]))) = + htonl(static_cast(fragments_event_to_master_[4]->size() - VSOMEIP_SOMEIP_HEADER_SIZE)); + for (int i : its_indexes) { + udp_server_socket.send_to(boost::asio::buffer(*fragments_event_to_master_[i]), master_client); + } + } + } else if (test_mode_ == someip_tp_test::test_mode_e::DUPLICATE) { + if (someip_tp_test::number_of_fragments < 2) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + for (auto iter = fragments_event_to_master_.rbegin(); + iter != fragments_event_to_master_.rend(); iter++) { + udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); + // send insert 2nd last fragment twice + if (iter == fragments_event_to_master_.rbegin() + 1) { + udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); + } + } + } else { + if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { + if (someip_tp_test::number_of_fragments < 4) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + // send an event fragment with a different session ID first + vsomeip::message_buffer_t msg_incomplete(*fragments_event_to_master_[3]); + msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0x55; + msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0x55; + udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); + // send a request with a different service ID as well to test cleanup + msg_incomplete[VSOMEIP_SERVICE_POS_MIN] = 0xbb; + msg_incomplete[VSOMEIP_SERVICE_POS_MAX] = 0xbb; + msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0xbb; + msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0xbb; + udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); + + } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { + if (someip_tp_test::number_of_fragments < 5) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + // increase second last segment by 16 byte + increase_segment_back(fragments_event_to_master_[4], 16); + } + for (auto iter = fragments_event_to_master_.rbegin(); iter != fragments_event_to_master_.rend(); iter++) { + udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); + } + } + } + std::cout << __LINE__ << ": send event to master " << std::uint32_t(mode) << std::endl; + } + + for (const order_e mode : {order_e::ASCENDING, order_e::DESCENDING}) { + while (wait_for_all_fragments_received_as_server_) { + if (std::cv_status::timeout == + all_fragments_received_as_server_cond_.wait_for(all_fragments_received_as_server_lock, + std::chrono::seconds(20))) { + ADD_FAILURE() << "Didn't receive request from client within time: " << std::uint32_t(mode); + return; + } else { + EXPECT_EQ(someip_tp_test::number_of_fragments, fragments_received_as_server_.size()); + // create complete message from request of client + vsomeip::message_buffer_t its_request = create_full_message(fragments_received_as_server_); + if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP || + test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { + EXPECT_EQ(VSOMEIP_FULL_HEADER_SIZE + + someip_tp_test::number_of_fragments * (someip_tp_test::max_segment_size - 160), + its_request.size()); + } else { + EXPECT_EQ(VSOMEIP_FULL_HEADER_SIZE + + someip_tp_test::number_of_fragments * someip_tp_test::max_segment_size, + its_request.size()); + } + const vsomeip::client_t its_request_client = + VSOMEIP_BYTES_TO_WORD(its_request[VSOMEIP_CLIENT_POS_MIN], + its_request[VSOMEIP_CLIENT_POS_MAX]); + const vsomeip::session_t its_request_session = + VSOMEIP_BYTES_TO_WORD(its_request[VSOMEIP_SESSION_POS_MIN], + its_request[VSOMEIP_SESSION_POS_MAX]); + create_fragments(someip_tp_test::number_of_fragments, + someip_tp_test::service_slave.service_id, + someip_tp_test::service_slave.instance_id, + someip_tp_test::service_slave.method_id, + vsomeip::message_type_e::MT_RESPONSE, + its_request_client, + its_request_session, + &fragments_response_to_master_, + (test_mode_ == someip_tp_test::test_mode_e::OVERLAP || + test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) ? + vsomeip::tp::tp::tp_max_segment_length_ - 160: + vsomeip::tp::tp::tp_max_segment_length_); + // create complete message from response + vsomeip::message_buffer_t its_response = create_full_message(fragments_response_to_master_); + // change the message type of the response to request for comparison + its_response[VSOMEIP_MESSAGE_TYPE_POS] = static_cast(vsomeip::message_type_e::MT_REQUEST); + + EXPECT_EQ(its_response.size(), its_request.size()); + EXPECT_EQ(its_response, its_request); + EXPECT_EQ(0, std::memcmp(static_cast(&its_response[0]), + static_cast(&its_request[0]), + its_response.size())); + // send back response + fragments_received_as_server_.clear(); + EXPECT_GT(remote_client_request_port, 0); + boost::asio::ip::udp::socket::endpoint_type master_client(address_remote_, remote_client_request_port); + if (mode == order_e::ASCENDING) { + if (test_mode_ == someip_tp_test::test_mode_e::MIXED) { + if (someip_tp_test::number_of_fragments != 6) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + } else { + auto its_indexes = {4,2,0,1,3,5}; + std::cout << __LINE__ << ": using following predefined sequence to send back response to master: "; + for (auto i : its_indexes) { std::cout << i << ", "; } + std::cout << std::endl; + for (int i : its_indexes) { + udp_server_socket.send_to(boost::asio::buffer(*fragments_response_to_master_[i]), master_client); + } + } + } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { + if (someip_tp_test::number_of_fragments != 6) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + } else { + auto its_indexes = {0,2,4,3,5,1}; + std::cout << __LINE__ << ": using following predefined sequence to send response to master: "; + for (auto i : its_indexes) { std::cout << i << ", "; } + std::cout << std::endl; + // increase fourth segment by 16 byte at front and back + increase_segment_front_back(fragments_response_to_master_[3], 16); + increase_segment_front(fragments_response_to_master_[1], 16); + for (int i : its_indexes) { + udp_server_socket.send_to(boost::asio::buffer(*fragments_response_to_master_[i]), master_client); + } + } + } else if (test_mode_ == someip_tp_test::test_mode_e::DUPLICATE) { + if (someip_tp_test::number_of_fragments < 2) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + for (auto iter = fragments_response_to_master_.begin(); + iter != fragments_response_to_master_.end(); iter++) { + udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); + // send 2nd fragment twice + if (iter == fragments_response_to_master_.begin() + 1) { + udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); + // send a fragment with invalid segment size as well + decrease_segment_back(*iter, 16); + increase_segment_back(*iter, 7); + udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); + increase_segment_back(*iter, 9); + } + } + } else { + if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { + if (someip_tp_test::number_of_fragments < 5) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + // send an event fragment with a different session ID first + vsomeip::message_buffer_t msg_incomplete(*fragments_response_to_master_[4]); + msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0x99; + msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0x99; + udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); + // send a request with a different service ID as well to test cleanup + msg_incomplete[VSOMEIP_SERVICE_POS_MIN] = 0xaa; + msg_incomplete[VSOMEIP_SERVICE_POS_MAX] = 0xaa; + msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0xaa; + msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0xaa; + udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); + } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { + if (someip_tp_test::number_of_fragments < 2) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + // increase second segment by 16 byte + increase_segment_back(fragments_response_to_master_[1], 16); + } + for (const auto& frag : fragments_response_to_master_) { + udp_server_socket.send_to(boost::asio::buffer(*frag), master_client); + } + } + } else if (mode == order_e::DESCENDING) { + if (test_mode_ == someip_tp_test::test_mode_e::MIXED) { + std::vector its_indexes = create_shuffled_seqeuence(someip_tp_test::number_of_fragments); + std::cout << __LINE__ << ": using following random sequence to send back response to master: "; + for (auto i : its_indexes) { std::cout << i << ", "; } + std::cout << std::endl; + for ( int i : its_indexes) { + udp_server_socket.send_to(boost::asio::buffer(*fragments_response_to_master_[i]), master_client); + } + } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { + if (someip_tp_test::number_of_fragments != 6) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + } else { + auto its_indexes = {5,3,2,1,4,0}; + std::cout << __LINE__ << ": using following predefined sequence to send response to master: "; + for (auto i : its_indexes) { std::cout << i << ", "; } + std::cout << std::endl; + // increase fith segment by 16 byte at front and back + increase_segment_front_back(fragments_response_to_master_[4], 16); + for (int i : its_indexes) { + udp_server_socket.send_to(boost::asio::buffer(*fragments_response_to_master_[i]), master_client); + } + } + } else if (test_mode_ == someip_tp_test::test_mode_e::DUPLICATE) { + if (someip_tp_test::number_of_fragments < 2) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + for (auto iter = fragments_response_to_master_.rbegin(); + iter != fragments_response_to_master_.rend(); iter++) { + udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); + // send insert 2nd last fragment twice + if (iter == fragments_response_to_master_.rbegin() + 1) { + udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); + } + } + } else { + if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { + if (someip_tp_test::number_of_fragments < 4) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + // send an event fragment with a different session ID first + vsomeip::message_buffer_t msg_incomplete(*fragments_response_to_master_[3]); + msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0x66; + msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0x66; + udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); + // send a request with a different service ID as well to test cleanup + msg_incomplete[VSOMEIP_SERVICE_POS_MIN] = 0xef; + msg_incomplete[VSOMEIP_SERVICE_POS_MAX] = 0xef; + msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0xef; + msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0xef; + udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); + } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { + if (someip_tp_test::number_of_fragments < 5) { + ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; + return; + } + // increase second last segment by 16 byte + increase_segment_back(fragments_response_to_master_[4], 16); + } + for (auto iter = fragments_response_to_master_.rbegin(); + iter != fragments_response_to_master_.rend(); iter++) { + udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); + } + } + } + } + } + wait_for_all_fragments_received_as_server_ = true; + } + }); + + std::thread udp_server_receive_thread([&]() { + { + std::lock_guard its_lock(udp_sd_socket_mutex); + offer_service(&udp_sd_socket); + } + + bool keep_receiving(true); + std::vector receive_buffer(4096); + while (keep_receiving) { + boost::system::error_code error; + boost::asio::ip::udp::socket::endpoint_type its_remote_endpoint; + std::size_t bytes_transferred = udp_server_socket.receive_from( + boost::asio::buffer(receive_buffer, receive_buffer.capacity()), its_remote_endpoint, 0, error); + if (error) { + keep_receiving = false; + ADD_FAILURE() << __func__ << " error: " << error.message(); + return; + } else { + remote_client_request_port = its_remote_endpoint.port(); + std::uint32_t its_pos = 0; + while (bytes_transferred > 0) { + const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], + receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; + std::cout << __LINE__ << ": received request from master " << its_message_size << std::endl; + vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); + + vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], + receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); + vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], + receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); + EXPECT_EQ(someip_tp_test::service_slave.service_id, its_service); + EXPECT_EQ(someip_tp_test::service_slave.method_id, its_method); + vsomeip::message_impl msg; + EXPECT_TRUE(msg.deserialize(&its_deserializer)); + if (vsomeip::tp::tp::tp_flag_is_set(receive_buffer[its_pos + VSOMEIP_MESSAGE_TYPE_POS])) { + auto its_buffer = std::make_shared(&receive_buffer[its_pos], &receive_buffer[its_pos] + its_message_size); + + fragments_received_as_server_.push_back(its_buffer); + if (fragments_received_as_server_.size() == someip_tp_test::number_of_fragments) { + std::lock_guard its_lock(all_fragments_received_as_server_mutex_); + wait_for_all_fragments_received_as_server_ = false; + std::cout << __LINE__ << ": received all fragments as server" << std::endl; + all_fragments_received_as_server_cond_.notify_one(); + static int received_requests = 0; + if (++received_requests == 2) { + std::cout << __LINE__ << ": received all requests as server --> Finished" << std::endl; + keep_receiving = false; + } + } + } + its_pos += its_message_size; + bytes_transferred -= its_message_size; + } + } + } + }); + + send_thread.join(); + sd_receive_thread.join(); + udp_server_receive_thread.join(); + udp_server_send_thread.join(); + + if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { + std::cout << "Sleeping to let cleanup for unfinished TP message " + "trigger on master side..." << std::endl; + std::this_thread::sleep_for(std::chrono::seconds(11)); + } + // shutdown the server + call_shutdown_method(); + + boost::system::error_code ec; + udp_sd_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_sd_socket.close(ec); + udp_client_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_client_socket.close(ec); + udp_server_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); + udp_server_socket.close(ec); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + if(argc < 3) { + std::cerr << "Please pass an target, local IP address and test mode to this binary like: " + << argv[0] << " 10.0.3.1 10.0.3.202 TP_IN_SEQUENCE" << std::endl; + std::cerr << "Testmodes are [ IN_SEQUENCE, MIXED, INCOMPLETE, OVERLAP, OVERLAP_FRONT_BACK ]" << std::endl; + } else { + remote_address = argv[1]; + local_address = argv[2]; + std::string its_testmode = argv[3]; + if (its_testmode == std::string("IN_SEQUENCE")) { + ::testing::GTEST_FLAG(filter) = "*send_in_mode/0"; + } else if (its_testmode == std::string("MIXED")) { + ::testing::GTEST_FLAG(filter) = "*send_in_mode/1"; + } else if (its_testmode == std::string("INCOMPLETE")) { + ::testing::GTEST_FLAG(filter) = "*send_in_mode/2"; + } else if (its_testmode == std::string("DUPLICATE")) { + ::testing::GTEST_FLAG(filter) = "*send_in_mode/3"; + } else if (its_testmode == std::string("OVERLAP")) { + ::testing::GTEST_FLAG(filter) = "*send_in_mode/4"; + } else if (its_testmode == std::string("OVERLAP_FRONT_BACK")) { + ::testing::GTEST_FLAG(filter) = "*send_in_mode/5"; + } + } + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/someip_tp_tests/someip_tp_test_service.cpp b/test/network_tests/someip_tp_tests/someip_tp_test_service.cpp new file mode 100644 index 0000000..26fdf6d --- /dev/null +++ b/test/network_tests/someip_tp_tests/someip_tp_test_service.cpp @@ -0,0 +1,413 @@ +// Copyright (C) 2014-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include "../../implementation/endpoints/include/tp.hpp" + +#include "someip_tp_test_globals.hpp" + +class someip_tp_test_service { +public: + someip_tp_test_service(struct someip_tp_test::service_info _service_info, someip_tp_test::test_mode_e _testmode) : + service_info_(_service_info), + testmode_(_testmode), + app_(vsomeip::runtime::get()->create_application("someip_tp_test_service")), + wait_until_registered_(true), + wait_until_shutdown_method_called_(true), + wait_for_slave_subscription_(true), + number_notifications_of_slave_(0x0), + wait_for_slave_service_available_(true), + wait_for_two_responses_of_slave_(true), + number_responses_of_slave_(0), + wait_for_two_requests_of_slave_(true), + number_requests_from_slave_(0), + wait_for_two_notifications_of_slave_(true), + offer_thread_(std::bind(&someip_tp_test_service::run, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&someip_tp_test_service::on_state, this, + std::placeholders::_1)); + + // offer field + std::set its_eventgroups; + its_eventgroups.insert(_service_info.eventgroup_id); + app_->offer_event(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_eventgroups, + vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), + false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, service_info_.shutdown_method_id, + std::bind(&someip_tp_test_service::on_shutdown_method_called, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, service_info_.notify_method_id, + std::bind(&someip_tp_test_service::on_notify_method_called, this, + std::placeholders::_1)); + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, service_info_.method_id, + std::bind(&someip_tp_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_async_subscription_handler(service_info_.service_id, + 0x1, service_info_.eventgroup_id, + std::bind(&someip_tp_test_service::subscription_handler_async, + this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, + std::placeholders::_4, std::placeholders::_5)); + + // request remote service + app_->request_service(someip_tp_test::service_slave.service_id, + someip_tp_test::service_slave.instance_id); + its_eventgroups.clear(); + its_eventgroups.insert(someip_tp_test::service_slave.eventgroup_id); + app_->request_event(someip_tp_test::service_slave.service_id, + someip_tp_test::service_slave.instance_id, + someip_tp_test::service_slave.event_id, its_eventgroups, + vsomeip::event_type_e::ET_EVENT, + vsomeip::reliability_type_e::RT_UNRELIABLE); + app_->register_message_handler(someip_tp_test::service_slave.service_id, + someip_tp_test::service_slave.instance_id, + someip_tp_test::service_slave.event_id, + std::bind(&someip_tp_test_service::on_notification, this, + std::placeholders::_1)); + app_->subscribe(someip_tp_test::service_slave.service_id, + someip_tp_test::service_slave.instance_id, + someip_tp_test::service_slave.eventgroup_id, 0x0, + someip_tp_test::service_slave.event_id); + app_->register_availability_handler(someip_tp_test::service_slave.service_id, + someip_tp_test::service_slave.instance_id, + std::bind(&someip_tp_test_service::on_availability, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + app_->register_message_handler( + someip_tp_test::service_slave.service_id, + someip_tp_test::service_slave.instance_id, + someip_tp_test::service_slave.method_id, + std::bind(&someip_tp_test_service::on_response_from_slave, this, + std::placeholders::_1)); + app_->start(); + } + + ~someip_tp_test_service() { + offer_thread_.join(); + } + + void offer() { + app_->offer_service(service_info_.service_id, 0x1); + } + + void stop() { + app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); + app_->clear_all_handler(); + app_->stop(); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _available) { + if (_service == someip_tp_test::service_slave.service_id && + _instance == someip_tp_test::service_slave.instance_id && + _available) { + std::lock_guard its_lock(mutex_); + wait_for_slave_service_available_ = false; + condition_.notify_one(); + VSOMEIP_INFO << "Service available Service/Instance [" + << std::setw(4) << std::setfill('0') << std::hex << _service << "/" + << std::setw(4) << std::setfill('0') << std::hex << _instance << "]"; + } + } + + void on_message(const std::shared_ptr& _message) { + VSOMEIP_INFO << "Received a message with Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex << _message->get_session() + << "] size: " << std::dec << _message->get_payload()->get_length(); + auto response = vsomeip::runtime::get()->create_response(_message); + auto payload = vsomeip::runtime::get()->create_payload(_message->get_payload()->get_data(), _message->get_payload()->get_length()); + response->set_payload(payload); + app_->send(response); + if (++number_requests_from_slave_ == 2) { + std::lock_guard its_lock(mutex_); + wait_for_two_requests_of_slave_ = false; + condition_.notify_one(); + } + } + + void on_notification(const std::shared_ptr& _message) { + VSOMEIP_INFO << "Received a notification with Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex << _message->get_session() + << "] size: " << std::dec << _message->get_payload()->get_length(); + EXPECT_EQ(someip_tp_test::service_slave.service_id, _message->get_service()); + EXPECT_EQ(someip_tp_test::service_slave.event_id, _message->get_method()); + std::vector its_cmp_data = + generate_payload(someip_tp_test::number_of_fragments, + (testmode_ == someip_tp_test::test_mode_e::OVERLAP + || testmode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) ? + someip_tp_test::max_segment_size - 160 : + someip_tp_test::max_segment_size); + + std::vector its_rcv_data(_message->get_payload()->get_data(), + _message->get_payload()->get_data() + _message->get_payload()->get_length()); + EXPECT_EQ(its_cmp_data.size(), its_rcv_data.size()); + if (testmode_ == someip_tp_test::test_mode_e::OVERLAP) { + if (number_notifications_of_slave_ == 0) { //ASCENDING with 2nd segment too big + for (std::uint32_t i = 0; i < 16; i++) { + its_cmp_data[2 * (someip_tp_test::max_segment_size - 160) + i] = 0xff; + } + } else if (number_notifications_of_slave_ == 1) { + // DESCENDING with 2nd last segment too big + // no action as successive 4 byte at end of message would + // overwrite the beginning of the last segment which was received first + } + } + EXPECT_EQ(its_cmp_data, its_rcv_data); + EXPECT_EQ(0, std::memcmp(static_cast(&its_cmp_data[0]), + static_cast(&its_rcv_data[0]), + its_cmp_data.size())); + if (++number_notifications_of_slave_ == 2) { + std::lock_guard its_lock(mutex_); + wait_for_two_notifications_of_slave_ = false; + condition_.notify_one(); + } + } + + void on_shutdown_method_called(const std::shared_ptr &_message) { + app_->send(vsomeip::runtime::get()->create_response(_message)); + VSOMEIP_WARNING << "************************************************************"; + VSOMEIP_WARNING << "Shutdown method called -> going down!"; + VSOMEIP_WARNING << "************************************************************"; + std::lock_guard its_lock(mutex_); + wait_until_shutdown_method_called_ = false; + condition_.notify_one(); + } + + void on_notify_method_called(const std::shared_ptr &_message) { + (void)_message; + std::vector its_data = generate_payload(someip_tp_test::number_of_fragments, + (testmode_ == someip_tp_test::test_mode_e::OVERLAP) ? + someip_tp_test::max_segment_size - 160 : + someip_tp_test::max_segment_size); + std::shared_ptr its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data(its_data); + app_->notify(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_payload); + VSOMEIP_INFO << __func__ << " send event"; + notify_method_called_.set_value(true); + } + + void send_fragmented_request_to_slave() { + auto its_req = vsomeip::runtime::get()->create_request(); + its_req->set_service(someip_tp_test::service_slave.service_id); + its_req->set_instance(someip_tp_test::service_slave.instance_id); + its_req->set_method(someip_tp_test::service_slave.method_id); + std::vector its_data = generate_payload(someip_tp_test::number_of_fragments, + (testmode_ == someip_tp_test::test_mode_e::OVERLAP + || testmode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) ? + someip_tp_test::max_segment_size - 160 : + someip_tp_test::max_segment_size); + auto its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data(its_data); + its_req->set_payload(its_payload); + request_send_to_slave_ = its_req; + app_->send(its_req); + } + + void on_response_from_slave(const std::shared_ptr &_message) { + VSOMEIP_INFO << "Received a response from the slave with Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex << _message->get_session() + << "] size: " << std::dec << _message->get_payload()->get_length(); + EXPECT_EQ(someip_tp_test::service_slave.service_id, _message->get_service()); + EXPECT_EQ(someip_tp_test::service_slave.instance_id, _message->get_instance()); + EXPECT_EQ(someip_tp_test::service_slave.method_id, _message->get_method()); + std::vector its_resp_payload(_message->get_payload()->get_data(), + _message->get_payload()->get_data() + _message->get_payload()->get_length()); + std::vector its_req_payload(request_send_to_slave_->get_payload()->get_data(), + request_send_to_slave_->get_payload()->get_data() + request_send_to_slave_->get_payload()->get_length()); + if (testmode_ == someip_tp_test::test_mode_e::OVERLAP) { + if (number_responses_of_slave_ == 0) { //ASCENDING with 2nd segment too big + for (std::uint32_t i = 0; i < 16; i++) { + its_req_payload[2 * (someip_tp_test::max_segment_size - 160) + i] = 0xff; + } + } else if (number_responses_of_slave_ == 1) { + // DESCENDING with 2nd last segment too big + // no action as successive 4 byte at end of message would + // overwrite the beginning of the last segment which was received first + } + } + + EXPECT_EQ(its_req_payload.size(), its_resp_payload.size()); + EXPECT_EQ(its_req_payload, its_resp_payload); + EXPECT_EQ(0, std::memcmp(static_cast(&its_req_payload[0]), + static_cast(&its_resp_payload[0]), + its_req_payload.size())); + + if (++number_responses_of_slave_ < 2) { + send_fragmented_request_to_slave(); + } else { + std::lock_guard its_lock(mutex_); + wait_for_two_responses_of_slave_ = false; + condition_.notify_one(); + } + } + + std::vector generate_payload(std::uint32_t _number_of_fragments, + std::uint32_t _segment_size) { + std::vector its_data; + for (std::uint32_t i = 0; i < _number_of_fragments; i++) { + its_data.resize((i * _segment_size) + _segment_size, + static_cast(i)); + } + return its_data; + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + + while (wait_for_slave_service_available_) { + condition_.wait(its_lock); + } + send_fragmented_request_to_slave(); + + while (wait_for_two_responses_of_slave_) { + condition_.wait(its_lock); + } + EXPECT_EQ(2u, number_responses_of_slave_); + + while (wait_for_two_requests_of_slave_) { + condition_.wait(its_lock); + } + EXPECT_EQ(2u, number_requests_from_slave_); + + while (wait_for_two_notifications_of_slave_) { + condition_.wait(its_lock); + } + EXPECT_EQ(2u, number_notifications_of_slave_); + + while (wait_for_slave_subscription_) { + condition_.wait(its_lock); + } + // slave subscribed --> sent a notification + on_notify_method_called(vsomeip::runtime::get()->create_message()); + + while (wait_until_shutdown_method_called_) { + condition_.wait(its_lock); + } + stop(); + } + + void subscription_handler_async(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, + bool _subscribed, const std::function& _cbk) { + (void)_uid; + (void)_gid; + VSOMEIP_WARNING << __func__ << " " << std::hex << _client << " subscribed." << _subscribed; + static int was_called = 0; + was_called++; + EXPECT_EQ(1, was_called); + EXPECT_TRUE(_subscribed); + _cbk(true); + std::lock_guard its_lock(mutex_); + wait_for_slave_subscription_ = false; + condition_.notify_one(); + } + + +private: + struct someip_tp_test::service_info service_info_; + someip_tp_test::test_mode_e testmode_; + std::shared_ptr app_; + + bool wait_until_registered_; + bool wait_until_shutdown_method_called_; + std::mutex mutex_; + std::condition_variable condition_; + std::atomic wait_for_slave_subscription_; + std::atomic number_notifications_of_slave_; + std::promise notify_method_called_; + bool wait_for_slave_service_available_; + bool wait_for_two_responses_of_slave_; + std::uint32_t number_responses_of_slave_; + bool wait_for_two_requests_of_slave_; + std::uint32_t number_requests_from_slave_; + bool wait_for_two_notifications_of_slave_; + std::shared_ptr request_send_to_slave_; + std::thread offer_thread_; +}; + +someip_tp_test::test_mode_e its_testmode(someip_tp_test::test_mode_e::IN_SEQUENCE); + +TEST(someip_someip_tp_test, echo_requests) +{ + someip_tp_test_service its_sample(someip_tp_test::service, its_testmode); +} + + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if (argc < 2) { + std::cerr << "Please pass a test mode to this binary like: " + << argv[0] << " IN_SEQUENCE" << std::endl; + std::cerr << "Testmodes are [ IN_SEQUENCE, MIXED, INCOMPLETE, DUPLICATE, OVERLAP, OVERLAP_FRONT_BACK ]" << std::endl; + exit(1); + } + + std::string its_pased_testmode = argv[1]; + if (its_pased_testmode == std::string("IN_SEQUENCE")) { + its_testmode = someip_tp_test::test_mode_e::IN_SEQUENCE; + } else if (its_pased_testmode == std::string("MIXED")) { + its_testmode = someip_tp_test::test_mode_e::MIXED; + } else if (its_pased_testmode == std::string("INCOMPLETE")) { + its_testmode = someip_tp_test::test_mode_e::INCOMPLETE; + } else if (its_pased_testmode == std::string("DUPLICATE")) { + its_testmode = someip_tp_test::test_mode_e::DUPLICATE; + } else if (its_pased_testmode == std::string("OVERLAP")) { + its_testmode = someip_tp_test::test_mode_e::OVERLAP; + } else if (its_pased_testmode == std::string("OVERLAP_FRONT_BACK")) { + its_testmode = someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK; + } + + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master.json.in b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master.json.in new file mode 100644 index 0000000..26d9644 --- /dev/null +++ b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master.json.in @@ -0,0 +1,104 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_one_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_one_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_one_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x1111", + "is_field" : "false", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x2222", + "is_field" : "false", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x3333", + "is_field" : "false", + "is_reliable" : "true" + } + ] + } + ], + "routing":"subscribe_notify_one_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + }, + "supports_selective_broadcasts" : + { + "address" : "@TEST_IP_SLAVE@" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in new file mode 100644 index 0000000..7b4b606 --- /dev/null +++ b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in @@ -0,0 +1,77 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_one_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_one_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_one_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_one_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + }, + "supports_selective_broadcasts" : + { + "address" : "@TEST_IP_SLAVE@" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json.in b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json.in new file mode 100644 index 0000000..e5218b3 --- /dev/null +++ b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json.in @@ -0,0 +1,65 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_one_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_one_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_one_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001" + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002" + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003" + } + ], + "routing":"subscribe_notify_one_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + }, + "supports_selective_broadcasts" : + { + "address" : "@TEST_IP_SLAVE@" + } +} diff --git a/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json.in b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json.in new file mode 100644 index 0000000..a4283b9 --- /dev/null +++ b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json.in @@ -0,0 +1,104 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_one_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_one_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_one_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x4444", + "is_field" : "false", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x5555", + "is_field" : "false", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x6666", + "is_field" : "false", + "is_reliable" : "true" + } + ] + } + ], + "routing":"subscribe_notify_one_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + }, + "supports_selective_broadcasts" : + { + "address" : "@TEST_IP_MASTER@" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in new file mode 100644 index 0000000..1cb1feb --- /dev/null +++ b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in @@ -0,0 +1,77 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_one_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_one_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_one_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_one_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + }, + "supports_selective_broadcasts" : + { + "address" : "@TEST_IP_MASTER@" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json.in b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json.in new file mode 100644 index 0000000..138afae --- /dev/null +++ b/test/network_tests/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json.in @@ -0,0 +1,65 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_one_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_one_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_one_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004" + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005" + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006" + } + ], + "routing":"subscribe_notify_one_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + }, + "supports_selective_broadcasts" : + { + "address" : "@TEST_IP_MASTER@" + } +} diff --git a/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_globals.hpp b/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_globals.hpp new file mode 100644 index 0000000..047ded7 --- /dev/null +++ b/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_globals.hpp @@ -0,0 +1,35 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ +#define SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ + +namespace subscribe_notify_one_test { + +struct service_info { + vsomeip::service_t service_id; + vsomeip::instance_t instance_id; + vsomeip::method_t method_id; + vsomeip::event_t event_id; + vsomeip::eventgroup_t eventgroup_id; +}; + +static constexpr std::array service_infos = {{ + // placeholder to be consistent w/ client ids, service ids, app names + { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }, + // node 1 + { 0x1111, 0x1, 0x1111, 0x1111, 0x1000 }, + { 0x2222, 0x1, 0x2222, 0x2222, 0x2000 }, + { 0x3333, 0x1, 0x3333, 0x3333, 0x3000 }, + // node 2 + { 0x4444, 0x1, 0x4444, 0x4444, 0x4000 }, + { 0x5555, 0x1, 0x5555, 0x5555, 0x5000 }, + { 0x6666, 0x1, 0x6666, 0x6666, 0x6000 } +}}; + +static constexpr int notifications_to_send = 10; +} + +#endif /* SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh b/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh new file mode 100755 index 0000000..8569a10 --- /dev/null +++ b/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +if [ $# -lt 2 ] +then + echo "Please pass a json file and event reliability type to this script." + echo "For example: $0 subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json UDP" + exit 1 +fi + +# replace master with slave to be able display the correct json file to be used +# with the slave script +RELIABILITY_TYPE=$1 +MASTER_JSON_FILE=$2 +CLIENT_JSON_FILE=${MASTER_JSON_FILE/master/slave} + +FAIL=0 + +# Start the services +export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_one +export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE +./subscribe_notify_one_test_service 1 $RELIABILITY_TYPE & + +export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_two +export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE +./subscribe_notify_one_test_service 2 $RELIABILITY_TYPE & + +export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_three +export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE +./subscribe_notify_one_test_service 3 $RELIABILITY_TYPE & + +sleep 3 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting subscribe_notify_one_test_slave_starter.sh on slave LXC with parameters $CLIENT_JSON_FILE" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./subscribe_notify_one_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE\"" & + echo "remote ssh job id: $!" +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./subscribe_notify_one_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE" & +else + cat < +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "subscribe_notify_one_test_globals.hpp" + + +class subscribe_notify_one_test_service { +public: + subscribe_notify_one_test_service(struct subscribe_notify_one_test::service_info _service_info, vsomeip::reliability_type_e _reliability_type) : + service_info_(_service_info), + app_(vsomeip::runtime::get()->create_application()), + wait_until_registered_(true), + wait_until_other_services_available_(true), + wait_until_notified_from_other_services_(true), + offer_thread_(std::bind(&subscribe_notify_one_test_service::run, this)), + wait_for_stop_(true), + stop_thread_(std::bind(&subscribe_notify_one_test_service::wait_for_stop, this)), + wait_for_notify_(true), + notify_thread_(std::bind(&subscribe_notify_one_test_service::notify_one, this)), + subscription_state_handler_called_(0), + subscription_error_occured_(false), + reliability_type_(_reliability_type) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&subscribe_notify_one_test_service::on_state, this, + std::placeholders::_1)); + + // offer event + std::set its_eventgroups; + its_eventgroups.insert(service_info_.eventgroup_id); + app_->offer_event(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_eventgroups, vsomeip::event_type_e::ET_SELECTIVE_EVENT, + std::chrono::milliseconds::zero(), false, true, nullptr, + reliability_type_); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.method_id, + std::bind(&subscribe_notify_one_test_service::on_request, this, + std::placeholders::_1)); + + // register subscription handler to detect whether or not all other + // other services have subscribed + app_->register_subscription_handler(service_info_.service_id, + service_info_.instance_id, service_info_.eventgroup_id, + std::bind(&subscribe_notify_one_test_service::on_subscription, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4)); + + // register availability for all other services and request their event. + for(const auto& i : subscribe_notify_one_test::service_infos) { + if ((i.service_id == service_info_.service_id + && i.instance_id == service_info_.instance_id) + || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { + continue; + } + app_->register_message_handler(i.service_id, + i.instance_id, vsomeip::ANY_METHOD, + std::bind(&subscribe_notify_one_test_service::on_message, this, + std::placeholders::_1)); + app_->register_availability_handler(i.service_id, i.instance_id, + std::bind(&subscribe_notify_one_test_service::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + app_->request_service(i.service_id, i.instance_id, vsomeip::DEFAULT_MAJOR, vsomeip::DEFAULT_MINOR); + + auto handler = std::bind(&subscribe_notify_one_test_service::on_subscription_state_change, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4, std::placeholders::_5); + app_->register_subscription_status_handler(i.service_id, i.instance_id, i.eventgroup_id, vsomeip::ANY_EVENT, handler); + app_->register_subscription_status_handler(vsomeip::ANY_SERVICE, i.instance_id, i.eventgroup_id, vsomeip::ANY_EVENT, handler); + app_->register_subscription_status_handler(i.service_id, vsomeip::ANY_INSTANCE, i.eventgroup_id, vsomeip::ANY_EVENT, handler); + app_->register_subscription_status_handler(vsomeip::ANY_SERVICE, vsomeip::ANY_INSTANCE, i.eventgroup_id, vsomeip::ANY_EVENT, handler); + + std::set its_eventgroups; + its_eventgroups.insert(i.eventgroup_id); + app_->request_event(i.service_id, i.instance_id, i.event_id, its_eventgroups, vsomeip::event_type_e::ET_SELECTIVE_EVENT, reliability_type_); + + other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; + other_services_received_notification_[std::make_pair(i.service_id, i.method_id)] = 0; + } + + app_->start(); + } + + ~subscribe_notify_one_test_service() { + offer_thread_.join(); + stop_thread_.join(); + } + + void offer() { + app_->offer_service(service_info_.service_id, service_info_.instance_id); + } + + void stop_offer() { + app_->stop_offer_event(service_info_.service_id, service_info_.instance_id, service_info_.event_id); + app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_DEBUG << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + if(_is_available) { + auto its_service = other_services_available_.find(std::make_pair(_service, _instance)); + if(its_service != other_services_available_.end()) { + if(its_service->second != _is_available) { + its_service->second = true; + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Service [" + << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance + << "] is available."; + + } + } + + if(std::all_of(other_services_available_.cbegin(), + other_services_available_.cend(), + [](const std::map, bool>::value_type& v) { + return v.second;})) { + std::lock_guard its_lock(mutex_); + wait_until_other_services_available_ = false; + condition_.notify_one(); + } + } + } + + void on_subscription_state_change(const vsomeip::service_t _service, const vsomeip::instance_t _instance, + const vsomeip::eventgroup_t _eventgroup, const vsomeip::event_t _event, const uint16_t _error) { + (void)_service; + (void)_instance; + (void)_eventgroup; + (void)_event; + if (!_error) { + subscription_state_handler_called_++; + } else { + subscription_error_occured_ = true; + VSOMEIP_ERROR << std::hex << app_->get_client() + << " : on_subscription_state_change: for service " << std::hex + << _service << " received a subscription error!"; + } + + } + + bool on_subscription(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) { + (void)_uid; + (void)_gid; + std::lock_guard its_subscribers_lock(subscribers_mutex_); + + // check if all other services have subscribed: + // -1 for placeholder in array and -1 for the service itself + if (subscribers_.size() == subscribe_notify_one_test::service_infos.size() - 2) { + return true; + } + + if (_subscribed) { + subscribers_.insert(_client); + } else { + subscribers_.erase(_client); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] " << "Client: " << _client + << " subscribed, now have " << std::dec << subscribers_.size() + << " subscribers. Expecting " << std::dec + << subscribe_notify_one_test::service_infos.size() - 2; + + if (subscribers_.size() == subscribe_notify_one_test::service_infos.size() - 2) + { + // notify the notify thread to start sending out notifications + std::lock_guard its_lock(notify_mutex_); + wait_for_notify_ = false; + notify_condition_.notify_one(); + } + return true; + } + + void on_request(const std::shared_ptr &_message) { + if(_message->get_message_type() == vsomeip::message_type_e::MT_REQUEST) { + VSOMEIP_DEBUG << "Received a request with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_session() << "]"; + std::shared_ptr its_response = vsomeip::runtime::get() + ->create_response(_message); + app_->send(its_response); + } + } + + void on_message(const std::shared_ptr &_message) { + if (_message->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + + other_services_received_notification_[std::make_pair(_message->get_service(), + _message->get_method())]++; + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] " + << "Received a notification with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_session() << "] from Service/Method [" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_service() << "/" << std::setw(4) << std::setfill('0') + << std::hex << _message->get_method() <<"] (now have: " + << std::dec << other_services_received_notification_[std::make_pair(_message->get_service(), + _message->get_method())] << ")"; + + if (all_notifications_received()) { + std::lock_guard its_lock(stop_mutex_); + wait_for_stop_ = false; + stop_condition_.notify_one(); + } + } + } + + bool all_notifications_received() { + return std::all_of( + other_services_received_notification_.cbegin(), + other_services_received_notification_.cend(), + [&](const std::map, std::uint32_t>::value_type& v) + { + return v.second == subscribe_notify_one_test::notifications_to_send; + } + ); + } + + bool all_notifications_received_tcp_and_udp() { + std::uint32_t received_twice(0); + std::uint32_t received_normal(0); + for(const auto &v : other_services_received_notification_) { + if (v.second == subscribe_notify_one_test::notifications_to_send * 2) { + received_twice++; + } else if(v.second == subscribe_notify_one_test::notifications_to_send) { + received_normal++; + } + } + + if( received_twice == (subscribe_notify_one_test::service_infos.size() - 1) / 2 + && received_normal == (subscribe_notify_one_test::service_infos.size() - 1) / 2 - 1) { + // routing manager stub receives the notification + // - twice from external nodes + // - and normal from all internal nodes + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] " + << "Received notifications:" + << " Normal: " << received_normal + << " Twice: " << received_twice; + return true; + } + return false; + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + + + while (wait_until_other_services_available_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Subscribing"; + // subscribe to events of other services + uint32_t subscribe_count = 0; + for(const subscribe_notify_one_test::service_info& i: subscribe_notify_one_test::service_infos) { + if ((i.service_id == service_info_.service_id + && i.instance_id == service_info_.instance_id) + || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { + continue; + } + + ++subscribe_count; + app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, + vsomeip::DEFAULT_MAJOR); + + VSOMEIP_DEBUG << "[" << std::hex << service_info_.service_id + << "] subscribing to Service/Instance/Eventgroup [" + << std::setw(4) << std::setfill('0') << std::hex << i.service_id << "/" + << std::setw(4) << std::setfill('0') << std::hex << i.instance_id + << "/" << std::setw(4) << std::setfill('0') << std::hex << i.eventgroup_id <<"]"; + + } + + while (wait_until_notified_from_other_services_) { + condition_.wait(its_lock); + } + + // It is possible that we run in the case a subscription is NACKED + // due to TCP endpoint not completely connected when subscription + // is processed in the server - due to resubscribing the error handler + // count may differ from expected value, but its not a real but as + // the subscription takes places anyways and all events will be received. + if (!subscription_error_occured_) { + // 4 * subscribe count cause we installed three additional wild-card handlers + ASSERT_EQ(subscribe_count * 4, subscription_state_handler_called_); + } else { + VSOMEIP_ERROR << "Subscription state handler check skipped: CallCount=" + << std::dec << subscription_state_handler_called_; + } + } + + void notify_one() { + std::unique_lock its_lock(notify_mutex_); + while(wait_for_notify_) { + notify_condition_.wait(its_lock); + } + + // sleep a while before starting to notify this is necessary as it's not + // possible to detect if _all_ clients on the remote side have + // successfully subscribed as we only receive once subscription per + // remote node no matter how many clients subscribed to this eventgroup + // on the remote node + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + + for(uint32_t i = 0; i < subscribe_notify_one_test::notifications_to_send; i++) { + std::shared_ptr its_payload = + vsomeip::runtime::get()->create_payload(); + + vsomeip::byte_t its_data[10] = {0}; + for (uint32_t j = 0; j < i+1; ++j) { + its_data[j] = static_cast(j); + } + its_payload->set_data(its_data, i+1); + + for (vsomeip::client_t client : subscribers_) { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Notifying client: " + << client << " : " << i+1; + app_->notify_one(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_payload, client); + } + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + } + + void wait_for_stop() { + std::unique_lock its_lock(stop_mutex_); + while (wait_for_stop_) { + stop_condition_.wait(its_lock); + } + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id + << "] Received notifications from all other services, going down"; + + // wait until all notifications have been sent out + notify_thread_.join(); + + // let offer thread exit + { + std::lock_guard its_lock(mutex_); + wait_until_notified_from_other_services_ = false; + condition_.notify_one(); + } + + stop_offer(); + + // ensure that the service which hosts the routing doesn't exit to early + if (app_->is_routing()) { + for (const auto& i : subscribe_notify_one_test::service_infos) { + if ((i.service_id == service_info_.service_id + && i.instance_id == service_info_.instance_id) + || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { + continue; + } + while (app_->is_available(i.service_id, i.instance_id, + vsomeip::ANY_MAJOR, vsomeip::ANY_MINOR)) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } + } + + for(const auto& i : subscribe_notify_one_test::service_infos) { + if ((i.service_id == service_info_.service_id + && i.instance_id == service_info_.instance_id) + || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { + continue; + } + app_->unregister_subscription_status_handler(i.service_id, i.instance_id, + i.eventgroup_id, vsomeip::ANY_EVENT); + app_->unsubscribe(i.service_id, i.instance_id, i.eventgroup_id); + app_->release_event(i.service_id, i.instance_id, i.event_id); + app_->release_service(i.service_id, i.instance_id); + } + std::this_thread::sleep_for(std::chrono::seconds(1)); + app_->clear_all_handler(); + app_->stop(); + } + +private: + subscribe_notify_one_test::service_info service_info_; + std::shared_ptr app_; + std::map, bool> other_services_available_; + std::map, std::uint32_t> other_services_received_notification_; + + bool wait_until_registered_; + bool wait_until_other_services_available_; + bool wait_until_notified_from_other_services_; + std::mutex mutex_; + std::condition_variable condition_; + std::thread offer_thread_; + + bool wait_for_stop_; + std::mutex stop_mutex_; + std::condition_variable stop_condition_; + std::thread stop_thread_; + + bool wait_for_notify_; + std::mutex notify_mutex_; + std::condition_variable notify_condition_; + std::thread notify_thread_; + + std::unordered_set subscribers_; + std::atomic subscription_state_handler_called_; + std::atomic subscription_error_occured_; + + std::mutex subscribers_mutex_; + vsomeip::reliability_type_e reliability_type_; +}; + +static unsigned long service_number; +vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN; + + +TEST(someip_subscribe_notify_one_test, send_ten_notifications_to_service) +{ + subscribe_notify_one_test_service its_sample( + subscribe_notify_one_test::service_infos[service_number], + reliability_type); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 3) { + std::cerr << "Please specify a service number and event reliability type, like: " << argv[0] << " 2 UDP" << std::endl; + std::cerr << "Valid service numbers are in the range of [1,6]" << std::endl; + std::cerr << "Valid service reliability types are [UDP, TCP, TCP_AND_UDP]" << std::endl; + + return 1; + } + + service_number = std::stoul(std::string(argv[1]), nullptr); + + if (std::string("TCP")== std::string(argv[2])) { + reliability_type = vsomeip::reliability_type_e::RT_RELIABLE; + } else if (std::string("UDP")== std::string(argv[2])) { + reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE; + } else if (std::string("TCP_AND_UDP")== std::string(argv[2])) { + reliability_type = vsomeip::reliability_type_e::RT_BOTH; + } + + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh b/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh new file mode 100755 index 0000000..830484d --- /dev/null +++ b/test/network_tests/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +if [ $# -lt 2 ] +then + echo "Please pass a json file and event reliability type to this script." + echo "For example: $0 UDP subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json" + exit 1 +fi + +FAIL=0 +# Start the services +export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_four +export VSOMEIP_CONFIGURATION=$2 +./subscribe_notify_one_test_service 4 $1 & + +export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_five +export VSOMEIP_CONFIGURATION=$2 +./subscribe_notify_one_test_service 5 $1 & + +export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_six +export VSOMEIP_CONFIGURATION=$2 +./subscribe_notify_one_test_service 6 $1 & + +sleep 3 + +# Wait until all applications are finished +for job in $(jobs -p) +do + # Fail gets incremented if one of the binaries exits + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +# Check if both exited successfully +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master.json.in new file mode 100644 index 0000000..370cf98 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master.json.in @@ -0,0 +1,60 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + } + ], + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master_local_tcp.json.in new file mode 100644 index 0000000..1ce1a05 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master_local_tcp.json.in @@ -0,0 +1,68 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + } + ], + "routing" : + { + "host" : + { + "unicast" : "127.0.0.1", + "port" : "31490" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave.json.in new file mode 100644 index 0000000..46de8ff --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave.json.in @@ -0,0 +1,60 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + } + ], + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave_local_tcp.json.in new file mode 100644 index 0000000..46865e4 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave_local_tcp.json.in @@ -0,0 +1,68 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + } + ], + "routing" : + { + "host" : + { + "unicast" : "127.0.0.1", + "port" : "31490" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master.json.in new file mode 100644 index 0000000..87299aa --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master.json.in @@ -0,0 +1,76 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_local_tcp.json.in new file mode 100644 index 0000000..b66fabc --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_local_tcp.json.in @@ -0,0 +1,83 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_one", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp.json.in new file mode 100644 index 0000000..99bf69a --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp.json.in @@ -0,0 +1,73 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp_local_tcp.json.in new file mode 100644 index 0000000..817a4ee --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp_local_tcp.json.in @@ -0,0 +1,80 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_one", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_udp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_udp.json.in new file mode 100644 index 0000000..cb66202 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_udp.json.in @@ -0,0 +1,61 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001" + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002" + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003" + } + ], + "routing": "subscribe_notify_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_udp_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_udp_local_tcp.json.in new file mode 100644 index 0000000..4fe8882 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_udp_local_tcp.json.in @@ -0,0 +1,68 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001" + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002" + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003" + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_one", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp.json.in new file mode 100644 index 0000000..4de283c --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp.json.in @@ -0,0 +1,61 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001" + }, + { + "service":"0x1111", + "instance":"0x0002", + "unreliable":"30002" + }, + { + "service":"0x1111", + "instance":"0x0003", + "unreliable":"30003" + } + ], + "routing":"subscribe_notify_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp_local_tcp.json.in new file mode 100644 index 0000000..5960b61 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp_local_tcp.json.in @@ -0,0 +1,68 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001" + }, + { + "service":"0x1111", + "instance":"0x0002", + "unreliable":"30002" + }, + { + "service":"0x1111", + "instance":"0x0003", + "unreliable":"30003" + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_one", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp.json.in new file mode 100644 index 0000000..5dd9299 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp.json.in @@ -0,0 +1,61 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30004" + }, + { + "service":"0x2222", + "instance":"0x0002", + "unreliable":"30005" + }, + { + "service":"0x2222", + "instance":"0x0003", + "unreliable":"30006" + } + ], + "routing":"subscribe_notify_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp_local_tcp.json.in new file mode 100644 index 0000000..2521d62 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp_local_tcp.json.in @@ -0,0 +1,68 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30004" + }, + { + "service":"0x2222", + "instance":"0x0002", + "unreliable":"30005" + }, + { + "service":"0x2222", + "instance":"0x0003", + "unreliable":"30006" + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_four", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave.json.in new file mode 100644 index 0000000..5b110aa --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave.json.in @@ -0,0 +1,76 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_local_tcp.json.in new file mode 100644 index 0000000..0b2ebb8 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_local_tcp.json.in @@ -0,0 +1,83 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_four", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp.json.in new file mode 100644 index 0000000..628734c --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp.json.in @@ -0,0 +1,73 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp_local_tcp.json.in new file mode 100644 index 0000000..14e5340 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp_local_tcp.json.in @@ -0,0 +1,85 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_four", + "unicast" : "127.0.0.1", + "port" : "44000" + }, + "guests" : + { + "ports" : [ { "first" : "44100", "last" : "44105" } ] + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp.json.in new file mode 100644 index 0000000..5b96b0e --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp.json.in @@ -0,0 +1,61 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004" + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005" + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006" + } + ], + "routing":"subscribe_notify_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp_local_tcp.json.in new file mode 100644 index 0000000..e4e75db --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp_local_tcp.json.in @@ -0,0 +1,68 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004" + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005" + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006" + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_four", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_master.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_master.json.in new file mode 100644 index 0000000..81bb18e --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_master.json.in @@ -0,0 +1,76 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_master_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_master_local_tcp.json.in new file mode 100644 index 0000000..acae8bb --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_master_local_tcp.json.in @@ -0,0 +1,83 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_one", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_slave.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_slave.json.in new file mode 100644 index 0000000..98ce9a6 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_slave.json.in @@ -0,0 +1,76 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_slave_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_slave_local_tcp.json.in new file mode 100644 index 0000000..7c1762d --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_slave_local_tcp.json.in @@ -0,0 +1,83 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_four", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master.json.in new file mode 100644 index 0000000..253b55e --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master.json.in @@ -0,0 +1,76 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_local_tcp.json.in new file mode 100644 index 0000000..f44a020 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_local_tcp.json.in @@ -0,0 +1,83 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_one", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp.json.in new file mode 100644 index 0000000..3969684 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp.json.in @@ -0,0 +1,73 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp_local_tcp.json.in new file mode 100644 index 0000000..7bc81cc --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp_local_tcp.json.in @@ -0,0 +1,80 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_one", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_udp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_udp.json.in new file mode 100644 index 0000000..72b53fc --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_udp.json.in @@ -0,0 +1,61 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000" + } + ], + "routing":"subscribe_notify_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_udp_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_udp_local_tcp.json.in new file mode 100644 index 0000000..25a017b --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_udp_local_tcp.json.in @@ -0,0 +1,68 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000" + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_one", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave.json.in new file mode 100644 index 0000000..556b10f --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave.json.in @@ -0,0 +1,76 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_local_tcp.json.in new file mode 100644 index 0000000..85847ea --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_local_tcp.json.in @@ -0,0 +1,83 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_four", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp.json.in new file mode 100644 index 0000000..3f9aa0b --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp.json.in @@ -0,0 +1,73 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp_local_tcp.json.in new file mode 100644 index 0000000..4aa32f1 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp_local_tcp.json.in @@ -0,0 +1,80 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_four", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_udp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_udp.json.in new file mode 100644 index 0000000..6e14f4f --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_udp.json.in @@ -0,0 +1,61 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000" + } + ], + "routing": "subscribe_notify_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_udp_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_udp_local_tcp.json.in new file mode 100644 index 0000000..baf3634 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_udp_local_tcp.json.in @@ -0,0 +1,68 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000" + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000" + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_four", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_master.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_master.json.in new file mode 100644 index 0000000..88d5ec9 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_master.json.in @@ -0,0 +1,31 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "logging" : + { + "level" : "warning", + "console" : "true", + "file" : { "enable" : "false", "path" : "/var/log/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "subscribe_notify_test_client", + "id" : "0x9999" + } + ], + "routing" : "routingmanagerd", + "service-discovery" : + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "0", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_master_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_master_local_tcp.json.in new file mode 100644 index 0000000..45e3943 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_master_local_tcp.json.in @@ -0,0 +1,38 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "logging" : + { + "level" : "warning", + "console" : "true", + "file" : { "enable" : "false", "path" : "/var/log/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "subscribe_notify_test_client", + "id" : "0x9999" + } + ], + "routing" : + { + "host" : + { + "name" : "routingmanagerd", + "unicast" : "127.0.0.1" + } + }, + "service-discovery" : + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "0", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_tcp_slave.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_tcp_slave.json.in new file mode 100644 index 0000000..f712c07 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_tcp_slave.json.in @@ -0,0 +1,39 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "logging" : + { + "level" : "warning", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "subscribe_notify_test_service", + "id" : "0x8888" + } + ], + "services" : + [ + { + "service" : "0xcafe", + "instance" : "0x1", + "reliable" : { "port":"30509", "enable-magic-cookies":"false" } + } + ], + "routing" : "routingmanagerd", + "service-discovery" : + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "0", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_tcp_slave_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_tcp_slave_local_tcp.json.in new file mode 100644 index 0000000..d87eb34 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_tcp_slave_local_tcp.json.in @@ -0,0 +1,46 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "logging" : + { + "level" : "info", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "subscribe_notify_test_service", + "id" : "0x8888" + } + ], + "services" : + [ + { + "service" : "0xcafe", + "instance" : "0x1", + "reliable" : { "port":"30509", "enable-magic-cookies":"false" } + } + ], + "routing" : + { + "host" : + { + "name" : "routingmanagerd", + "unicast" : "127.0.0.1" + } + }, + "service-discovery" : + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "0", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_udp_slave.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_udp_slave.json.in new file mode 100644 index 0000000..cd6415c --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_udp_slave.json.in @@ -0,0 +1,39 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "logging" : + { + "level" : "warning", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "subscribe_notify_test_service", + "id" : "0x8888" + } + ], + "services" : + [ + { + "service" : "0xcafe", + "instance" : "0x1", + "unreliable" : "30509" + } + ], + "routing" : "routingmanagerd", + "service-discovery" : + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "0", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_udp_slave_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_udp_slave_local_tcp.json.in new file mode 100644 index 0000000..a596b30 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_udp_slave_local_tcp.json.in @@ -0,0 +1,46 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "logging" : + { + "level" : "warning", + "console" : "true", + "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "subscribe_notify_test_service", + "id" : "0x8888" + } + ], + "services" : + [ + { + "service" : "0xcafe", + "instance" : "0x1", + "unreliable" : "30509" + } + ], + "routing" : + { + "host" : + { + "name" : "routingmanagerd", + "unicast" : "127.0.0.1" + } + }, + "service-discovery" : + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "0", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_master.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_master.json.in new file mode 100644 index 0000000..87299aa --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_master.json.in @@ -0,0 +1,76 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_master_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_master_local_tcp.json.in new file mode 100644 index 0000000..b66fabc --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_master_local_tcp.json.in @@ -0,0 +1,83 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_one", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_slave.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_slave.json.in new file mode 100644 index 0000000..bc13f01 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_slave.json.in @@ -0,0 +1,76 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_slave_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_slave_local_tcp.json.in new file mode 100644 index 0000000..654ec65 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_slave_local_tcp.json.in @@ -0,0 +1,83 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"info", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_four", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_master.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_master.json.in new file mode 100644 index 0000000..253b55e --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_master.json.in @@ -0,0 +1,76 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_master_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_master_local_tcp.json.in new file mode 100644 index 0000000..f44a020 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_master_local_tcp.json.in @@ -0,0 +1,83 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_one", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_slave.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_slave.json.in new file mode 100644 index 0000000..c203e80 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_slave.json.in @@ -0,0 +1,76 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing":"subscribe_notify_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_slave_local_tcp.json.in b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_slave_local_tcp.json.in new file mode 100644 index 0000000..91e9006 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_slave_local_tcp.json.in @@ -0,0 +1,83 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + } + } + ], + "routing": + { + "host" : + { + "name" : "subscribe_notify_test_service_four", + "unicast" : "127.0.0.1" + } + }, + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/subscribe_notify_tests/subscribe_notify_test_globals.hpp b/test/network_tests/subscribe_notify_tests/subscribe_notify_test_globals.hpp new file mode 100644 index 0000000..761c3c4 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/subscribe_notify_test_globals.hpp @@ -0,0 +1,55 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ +#define SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ + +namespace subscribe_notify_test { + +struct service_info { + vsomeip::service_t service_id; + vsomeip::instance_t instance_id; + vsomeip::method_t method_id; + vsomeip::event_t event_id; + vsomeip::eventgroup_t eventgroup_id; +}; + +static constexpr std::array service_infos = {{ + // placeholder to be consistent w/ client ids, service ids, app names + { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }, + // node 1 + { 0x1111, 0x1, 0x1111, 0x1111, 0x1000 }, + { 0x2222, 0x1, 0x2222, 0x2222, 0x2000 }, + { 0x3333, 0x1, 0x3333, 0x3333, 0x3000 }, + // node 2 + { 0x4444, 0x1, 0x4444, 0x4444, 0x4000 }, + { 0x5555, 0x1, 0x5555, 0x5555, 0x5000 }, + { 0x6666, 0x1, 0x6666, 0x6666, 0x6000 } +}}; + +static constexpr std::array service_infos_same_service_id = {{ + // placeholder to be consistent w/ client ids, service ids, app names + { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }, + // node 1 + { 0x1111, 0x1, 0x1111, 0x1111, 0x1000 }, + { 0x1111, 0x2, 0x2222, 0x2222, 0x2000 }, + { 0x1111, 0x3, 0x3333, 0x3333, 0x3000 }, + // node 2 + { 0x2222, 0x1, 0x4444, 0x4444, 0x4000 }, + { 0x2222, 0x2, 0x5555, 0x5555, 0x5000 }, + { 0x2222, 0x3, 0x6666, 0x6666, 0x6000 } +}}; + +static constexpr int notifications_to_send = 10; + +// one_event_two_eventgroups globals +static constexpr struct service_info service_info_subscriber_based_notification = + { 0xCAFE, 0x1, 0x8888, 0x8111, 0x1}; +static constexpr vsomeip::method_t shutdown_method_id = 0x6666; +static constexpr vsomeip::method_t set_method_id = 0x7777; + +} + +#endif /* SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ */ diff --git a/test/network_tests/subscribe_notify_tests/subscribe_notify_test_master_starter.sh b/test/network_tests/subscribe_notify_tests/subscribe_notify_test_master_starter.sh new file mode 100755 index 0000000..10dfd8e --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/subscribe_notify_test_master_starter.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +if [ $# -lt 1 ] +then + echo "Please pass a json file and event reliability type to this script." + echo "For example: $0 UDP subscribe_notify_test_diff_client_ids_diff_ports_master.json" + echo "To use the same service id but different instances on the node pass SAME_SERVICE_ID as third parameter" + exit 1 +fi + +# replace master with slave to be able display the correct json file to be used +# with the slave script +RELIABILITY_TYPE=$1 +MASTER_JSON_FILE=$2 +SAME_SERVICE_ID=$3 +CLIENT_JSON_FILE=${MASTER_JSON_FILE/master/slave} + +FAIL=0 + +# Start the services +export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_one +export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE +./subscribe_notify_test_service 1 $RELIABILITY_TYPE $3 & + +export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_two +export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE +./subscribe_notify_test_service 2 $RELIABILITY_TYPE $3 & + +export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_three +export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE +./subscribe_notify_test_service 3 $RELIABILITY_TYPE $3 & + +sleep 3 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting subscribe_notify_test_slave_starter.sh on slave LXC with parameters $CLIENT_JSON_FILE $2" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./subscribe_notify_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE $3\"" & + echo "remote ssh job id: $!" +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./subscribe_notify_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE $3" & +else + cat < +#endif +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "subscribe_notify_test_globals.hpp" + +class subscribe_notify_test_one_event_two_eventgroups_client { +public: + subscribe_notify_test_one_event_two_eventgroups_client( + struct subscribe_notify_test::service_info _info, bool _use_tcp) : + app_( + vsomeip::runtime::get()->create_application( + "subscribe_notify_test_client")), + info_(_info), + use_tcp_(_use_tcp), + wait_availability_(true), + wait_set_value_(true), + wait_shutdown_response_(true), + run_thread_(std::bind(&subscribe_notify_test_one_event_two_eventgroups_client::run, this)) { + } + ~subscribe_notify_test_one_event_two_eventgroups_client() { + run_thread_.join(); + } + + bool init() { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + + app_->register_state_handler( + std::bind( + &subscribe_notify_test_one_event_two_eventgroups_client::on_state, + this, std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, + std::bind( + &subscribe_notify_test_one_event_two_eventgroups_client::on_message, + this, std::placeholders::_1)); + + app_->register_availability_handler(info_.service_id, info_.instance_id, + std::bind( + &subscribe_notify_test_one_event_two_eventgroups_client::on_availability, + this, std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + std::set its_groups; + // the service offers three events in two eventgroups + // one of the events is in both eventgroups (info_.event_id + 2) + its_groups.insert(info_.eventgroup_id); + app_->request_event(info_.service_id, info_.instance_id, + info_.event_id, its_groups, + vsomeip::event_type_e::ET_FIELD, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); + app_->request_event(info_.service_id, info_.instance_id, + static_cast(info_.event_id + 2), + its_groups, vsomeip::event_type_e::ET_FIELD, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); + its_groups.erase(info_.eventgroup_id); + its_groups.insert(static_cast(info_.eventgroup_id +1)); + app_->request_event(info_.service_id, info_.instance_id, + static_cast(info_.event_id+1), + its_groups, vsomeip::event_type_e::ET_FIELD, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); + app_->request_event(info_.service_id, info_.instance_id, + static_cast(info_.event_id+2), + its_groups, vsomeip::event_type_e::ET_FIELD, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); + + return true; + } + + void start() { + app_->start(); + } + + void stop() { + app_->clear_all_handler(); + app_->unsubscribe(info_.service_id, info_.instance_id, info_.eventgroup_id); + app_->unsubscribe(info_.service_id, info_.instance_id, static_cast(info_.eventgroup_id+1)); + app_->release_event(info_.service_id, info_.instance_id, info_.event_id); + app_->release_event(info_.service_id, info_.instance_id, static_cast(info_.event_id+1)); + app_->release_event(info_.service_id, info_.instance_id, static_cast(info_.event_id+2)); + app_->release_service(info_.service_id, info_.instance_id); + app_->stop(); + } + + void on_state(vsomeip::state_type_e _state) { + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + app_->request_service(info_.service_id, info_.instance_id); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, + bool _is_available) { + VSOMEIP_DEBUG << "Service [" + << std::setw(4) << std::setfill('0') << std::hex << _service + << "." << _instance << "] is " + << (_is_available ? "available." : "NOT available."); + if (_service == info_.service_id && _instance == info_.instance_id && _is_available) { + std::lock_guard its_lock(availability_mutex_); + wait_availability_ = false; + availability_condition_.notify_one(); + } + } + + void on_message(const std::shared_ptr &_response) { + std::stringstream its_message; + its_message << "Received a message [" + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_service() << "." + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_instance() << "." + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_method() << "] from Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _response->get_session() + << "] = "; + std::shared_ptr its_payload = + _response->get_payload(); + its_message << "(" << std::dec << its_payload->get_length() << ") "; + for (uint32_t i = 0; i < its_payload->get_length(); ++i) + its_message << std::hex << std::setw(2) << std::setfill('0') + << (int) its_payload->get_data()[i] << " "; + VSOMEIP_DEBUG << its_message.str(); + ASSERT_EQ(info_.service_id, _response->get_service()); + + if (_response->get_method() == info_.method_id + || _response->get_method() == subscribe_notify_test::shutdown_method_id) { + ASSERT_EQ(vsomeip::message_type_e::MT_RESPONSE, _response->get_message_type()); + ASSERT_EQ(vsomeip::return_code_e::E_OK, _response->get_return_code()); + std::lock_guard its_lock(shutdown_response_mutex_); + wait_shutdown_response_ = false; + shutdown_response_condition_.notify_one(); + } else if (_response->get_method() == subscribe_notify_test::set_method_id) { + std::lock_guard its_lock(set_value_mutex_); + wait_set_value_ = false; + set_value_condition_.notify_one(); + } else if (_response->get_method() >= info_.event_id + && _response->get_method() <= static_cast(info_.event_id + 3)) { + std::lock_guard its_lock(events_mutex_); + received_events_.push_back(_response->get_payload()); + if (received_events_.size() > 4) { + ADD_FAILURE() << "Received too many events [" + << std::hex << _response->get_method() + << " (" << std::dec << received_events_.size() << ")"; + } + number_received_events_[_response->get_method()]++; + events_condition_.notify_one(); + } else { + ADD_FAILURE() << "Received unknown method id: " << std::setw(4) + << std::setfill('0') << std::hex << _response->get_method(); + } + + } + + void set_field_at_service(vsomeip::byte_t _value) { + std::shared_ptr its_runtime = vsomeip::runtime::get(); + std::shared_ptr its_request = its_runtime->create_request(false); + its_request->set_service(info_.service_id); + its_request->set_instance(info_.instance_id); + its_request->set_method(subscribe_notify_test::set_method_id); + its_request->set_reliable(use_tcp_); + std::shared_ptr its_payload = its_runtime->create_payload(&_value, sizeof(_value)); + its_request->set_payload(its_payload); + app_->send(its_request); + } + + void call_method_at_service(vsomeip::method_t _method) { + std::shared_ptr its_runtime = vsomeip::runtime::get(); + std::shared_ptr its_request = its_runtime->create_request(false); + its_request->set_service(info_.service_id); + its_request->set_instance(info_.instance_id); + its_request->set_method(_method); + its_request->set_reliable(use_tcp_); + app_->send(its_request); + } + + void wait_on_condition(std::unique_lock&& _lock, bool *_predicate, std::condition_variable&& _condition, std::uint32_t _timeout) { + while (*_predicate) { + if (std::cv_status::timeout == _condition.wait_for(_lock, std::chrono::seconds(_timeout))) { + ADD_FAILURE() << "Condition variable wasn't notified within time (" + << _timeout << "sec)"; + } + } + *_predicate = true; + } + + void subscribe_at_service() { + // subscribe to both eventgroups + app_->subscribe(info_.service_id, info_.instance_id, info_.eventgroup_id); + app_->subscribe(info_.service_id, info_.instance_id, static_cast(info_.eventgroup_id+1)); + } + + void unsubscribe_at_service() { + app_->unsubscribe(info_.service_id, info_.instance_id, info_.eventgroup_id); + app_->unsubscribe(info_.service_id, info_.instance_id, static_cast(info_.eventgroup_id+1)); + } + + void wait_for_events(std::unique_lock&& _lock, + std::uint32_t _expected_number_received_events, + std::condition_variable&& _condition) { + std::cv_status its_status(std::cv_status::no_timeout); + while (received_events_.size() != _expected_number_received_events + && its_status != std::cv_status::timeout) { + its_status = _condition.wait_for(_lock, std::chrono::seconds(15)); + if (std::cv_status::timeout == its_status) { + ADD_FAILURE() << "Didn't receive expected number of events: " + << _expected_number_received_events + << " within time. Instead received: " << received_events_.size(); + } + } + ASSERT_EQ(size_t(_expected_number_received_events), received_events_.size()); + } + + void check_received_events_payload(vsomeip::byte_t _value) { + for (const auto &p : received_events_) { + ASSERT_EQ(vsomeip::length_t(1), p->get_length()); + ASSERT_EQ(vsomeip::byte_t(_value), *p->get_data()); + } + received_events_.clear(); + } + + void check_received_events_number(std::set> _expected) { + for (const auto &e : _expected) { + auto event = number_received_events_.find(e.first); + ASSERT_NE(number_received_events_.end(), event); + ASSERT_EQ(e.second, event->second); + } + number_received_events_.clear(); + } + + void run() { + std::unique_lock its_availability_lock(availability_mutex_); + wait_on_condition(std::move(its_availability_lock), &wait_availability_, std::move(availability_condition_), 300); + // service is available now + + for (int i = 0; i < 3; i++) { + // set value + set_field_at_service(0x1); + { + std::unique_lock its_set_value_lock(set_value_mutex_); + wait_on_condition(std::move(its_set_value_lock), &wait_set_value_, std::move(set_value_condition_), 30); + } + + // subscribe + std::unique_lock its_events_lock(events_mutex_); + subscribe_at_service(); + wait_for_events(std::move(its_events_lock), 4, std::move(events_condition_)); + check_received_events_payload(0x1); + + std::set> its_expected; + its_expected.insert({info_.event_id, 1}); + its_expected.insert({static_cast(info_.event_id+1), 1}); + // Initial event for the event which is member of both eventgroups has to be sent twice + its_expected.insert({static_cast(info_.event_id+2), 2}); + + check_received_events_number(its_expected); + its_expected.clear(); + // set value again + set_field_at_service(0x2); + { + std::unique_lock its_set_value_lock(set_value_mutex_); + wait_on_condition(std::move(its_set_value_lock), &wait_set_value_, std::move(set_value_condition_), 30); + } + + wait_for_events(std::move(its_events_lock), 3, std::move(events_condition_)); + check_received_events_payload(0x2); + its_expected.insert({info_.event_id, 1}); + its_expected.insert({static_cast(info_.event_id+1), 1}); + its_expected.insert({static_cast(info_.event_id+2), 1}); + + check_received_events_number(its_expected); + its_expected.clear(); + + // set value again + set_field_at_service(0x3); + { + std::unique_lock its_set_value_lock(set_value_mutex_); + wait_on_condition(std::move(its_set_value_lock), &wait_set_value_, std::move(set_value_condition_), 30); + } + wait_for_events(std::move(its_events_lock), 3, std::move(events_condition_)); + check_received_events_payload(0x3); + its_expected.insert({info_.event_id, 1}); + its_expected.insert({static_cast(info_.event_id+1), 1}); + its_expected.insert({static_cast(info_.event_id+2), 1}); + check_received_events_number(its_expected); + + unsubscribe_at_service(); + // sleep some time to ensure the unsubscription was processed by the + // remote routing_manager before setting the field again in the next + // loop. + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + std::unique_lock its_shutdown_lock(shutdown_response_mutex_); + call_method_at_service(subscribe_notify_test::shutdown_method_id); + wait_on_condition(std::move(its_shutdown_lock), &wait_shutdown_response_, std::move(shutdown_response_condition_), 30); + stop(); + } + +private: + std::shared_ptr app_; + struct subscribe_notify_test::service_info info_; + bool use_tcp_; + + bool wait_availability_; + std::mutex availability_mutex_; + std::condition_variable availability_condition_; + + bool wait_set_value_; + std::mutex set_value_mutex_; + std::condition_variable set_value_condition_; + + bool wait_shutdown_response_; + std::mutex shutdown_response_mutex_; + std::condition_variable shutdown_response_condition_; + + std::mutex events_mutex_; + std::condition_variable events_condition_; + + std::vector> received_events_; + std::map number_received_events_; + std::thread run_thread_; +}; + +#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING + subscribe_notify_test_one_event_two_eventgroups_client *its_client_ptr(nullptr); + void handle_signal(int _signal) { + if (its_client_ptr != nullptr && + (_signal == SIGINT || _signal == SIGTERM)) + its_client_ptr->stop(); + } +#endif + +static bool use_tcp; + +TEST(someip_subscribe_notify_test_one_event_two_eventgroups, subscribe_to_service) +{ + subscribe_notify_test_one_event_two_eventgroups_client its_client( + subscribe_notify_test::service_info_subscriber_based_notification, use_tcp); +#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING + its_client_ptr = &its_client; + signal(SIGINT, handle_signal); + signal(SIGTERM, handle_signal); +#endif + if (its_client.init()) { + its_client.start(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a offer type of the service, like: " << argv[0] << " UDP" << std::endl; + std::cerr << "Valid offer types include:" << std::endl; + std::cerr << "[UDP, TCP]" << std::endl; + return 1; + } + + if(std::string("TCP") == std::string(argv[1])) { + use_tcp = true; + } else if(std::string("UDP") == std::string(argv[1])) { + use_tcp = false; + } else { + std::cerr << "Wrong subscription type passed, exiting" << std::endl; + std::cerr << "Valid subscription types include:" << std::endl; + std::cerr << "[UDP, TCP]" << std::endl; + return 1; + } + + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master_starter.sh b/test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master_starter.sh new file mode 100755 index 0000000..e379958 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master_starter.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +if [ $# -lt 2 ]; then + echo "Please pass a json file and a subscription type to this script." + echo "Valid subscription types include:" + echo " [UDP, TCP]" + echo "For example: $0 UDP subscribe_notify_test_one_event_two_eventgroups_master.json" + exit 1 +fi + +# replace master with slave to be able display the correct json file to be used +# with the slave script +RELIABILITY_TYPE=$1 +MASTER_JSON_FILE=$2 +if [ $1 == "UDP" ]; then + SLAVE_JSON_FILE=${MASTER_JSON_FILE/master/udp_slave} +elif [ $1 == "TCP" ]; then + SLAVE_JSON_FILE=${MASTER_JSON_FILE/master/tcp_slave} +fi + +FAIL=0 + +export VSOMEIP_CONFIGURATION=$2 +# start daemon +../../examples/routingmanagerd/routingmanagerd & +PID_VSOMEIPD=$! + +# Start the client +./subscribe_notify_test_one_event_two_eventgroups_client $1 & +PID_CLIENT=$! +sleep 1 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting subscribe_notify_test_slave_starter.sh on slave LXC with parameters $SLAVE_JSON_FILE" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh $RELIABILITY_TYPE $SLAVE_JSON_FILE\"" & + echo "remote ssh job id: $!" +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh $RELIABILITY_TYPE $SLAVE_JSON_FILE" & +else + cat < +#endif +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "subscribe_notify_test_globals.hpp" + +class subscribe_notify_test_one_event_two_eventgroups_service { +public: + subscribe_notify_test_one_event_two_eventgroups_service(subscribe_notify_test::service_info _info, bool _use_tcp) : + app_(vsomeip::runtime::get()->create_application()), + wait_for_shutdown_(true), + info_(_info), + notify_thread_(std::bind(&subscribe_notify_test_one_event_two_eventgroups_service::wait_for_shutdown, this)), + use_tcp_(_use_tcp) { + } + + ~subscribe_notify_test_one_event_two_eventgroups_service() { + notify_thread_.join(); + } + + bool init() { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + app_->register_state_handler( + std::bind(&subscribe_notify_test_one_event_two_eventgroups_service::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler( + info_.service_id, + info_.instance_id, + subscribe_notify_test::set_method_id, + std::bind(&subscribe_notify_test_one_event_two_eventgroups_service::on_set, this, + std::placeholders::_1)); + + app_->register_message_handler( + info_.service_id, + info_.instance_id, + info_.method_id, + std::bind(&subscribe_notify_test_one_event_two_eventgroups_service::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler( + info_.service_id, + info_.instance_id, + subscribe_notify_test::shutdown_method_id, + std::bind(&subscribe_notify_test_one_event_two_eventgroups_service::on_shutdown, this, + std::placeholders::_1)); + + std::set its_groups; + // the service offers three events in two eventgroups + // one of the events is in both eventgroups + its_groups.insert(info_.eventgroup_id); + app_->offer_event(info_.service_id, info_.instance_id, + info_.event_id, its_groups, vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), + false, true, nullptr, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); + app_->offer_event(info_.service_id, info_.instance_id, + static_cast(info_.event_id + 2), + its_groups, vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), + false, true, nullptr, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); + its_groups.erase(info_.eventgroup_id); + its_groups.insert(static_cast(info_.eventgroup_id + 1)); + app_->offer_event(info_.service_id, info_.instance_id, + static_cast(info_.event_id + 1), + its_groups, vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), + false, true, nullptr, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); + app_->offer_event(info_.service_id, info_.instance_id, + static_cast(info_.event_id + 2), + its_groups, vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), + false, true, nullptr, + (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); + payload_ = vsomeip::runtime::get()->create_payload(); + + return true; + } + + void start() { + app_->start(); + } + +#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING + /* + * Handle signal to shutdown + */ + void stop() { + { + std::lock_guard its_lock(shutdown_mutex_); + wait_for_shutdown_ = false; + shutdown_condition_.notify_one(); + } + app_->clear_all_handler(); + stop_offer(); + notify_thread_.join(); + app_->stop(); + } +#endif + + void offer() { + app_->offer_service(info_.service_id, info_.instance_id); + } + + void stop_offer() { + app_->stop_offer_service(info_.service_id, info_.instance_id); + } + + void on_state(vsomeip::state_type_e _state) { + std::cout << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered.") << std::endl; + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + offer(); + } + } + + void on_shutdown(const std::shared_ptr &_message) { + std::shared_ptr its_response + = vsomeip::runtime::get()->create_response(_message); + its_response->set_payload(payload_); + app_->send(its_response); + { + std::lock_guard its_lock(shutdown_mutex_); + wait_for_shutdown_ = false; + shutdown_condition_.notify_one(); + } + } + + void on_set(const std::shared_ptr &_message) { + std::shared_ptr its_response + = vsomeip::runtime::get()->create_response(_message); + payload_ = _message->get_payload(); + its_response->set_payload(payload_); + app_->send(its_response); + app_->notify(info_.service_id, info_.instance_id, info_.event_id, payload_); + app_->notify(info_.service_id, info_.instance_id, static_cast(info_.event_id + 1), payload_); + app_->notify(info_.service_id, info_.instance_id, static_cast(info_.event_id + 2), payload_); + } + + void on_message(const std::shared_ptr &_message) { + app_->send(vsomeip::runtime::get()->create_response(_message)); + } + + void wait_for_shutdown() { + { + std::unique_lock its_lock(shutdown_mutex_); + while (wait_for_shutdown_) { + shutdown_condition_.wait(its_lock); + } + wait_for_shutdown_= true; + } + + app_->clear_all_handler(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + stop_offer(); + app_->stop(); + } + +private: + std::shared_ptr app_; + + std::mutex shutdown_mutex_; + bool wait_for_shutdown_; + std::condition_variable shutdown_condition_; + + std::shared_ptr payload_; + + subscribe_notify_test::service_info info_; + + std::thread notify_thread_; + bool use_tcp_; +}; + +#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING + subscribe_notify_test_one_event_two_eventgroups_service *its_service_ptr(nullptr); + void handle_signal(int _signal) { + if (its_service_ptr != nullptr && + (_signal == SIGINT || _signal == SIGTERM)) + its_service_ptr->stop(); + } +#endif + +static bool use_tcp; + +TEST(someip_subscribe_notify_test_one_event_two_eventgroups, wait_for_attribute_set) +{ + subscribe_notify_test_one_event_two_eventgroups_service its_service( + subscribe_notify_test::service_info_subscriber_based_notification, use_tcp); +#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING + its_service_ptr = &its_service; + signal(SIGINT, handle_signal); + signal(SIGTERM, handle_signal); +#endif + if (its_service.init()) { + its_service.start(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a offer type of the service, like: " << argv[0] << " UDP" << std::endl; + std::cerr << "Valid offer types include:" << std::endl; + std::cerr << "[UDP, TCP]" << std::endl; + return 1; + } + + if(std::string("TCP") == std::string(argv[1])) { + use_tcp = true; + } else if(std::string("UDP") == std::string(argv[1])) { + use_tcp = false; + } else { + std::cerr << "Wrong subscription type passed, exiting" << std::endl; + std::cerr << "Valid subscription types include:" << std::endl; + std::cerr << "[UDP, TCP]" << std::endl; + return 1; + } + + return RUN_ALL_TESTS(); +} +#endif + + diff --git a/test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh b/test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh new file mode 100755 index 0000000..8d8b54c --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +if [ $# -lt 2 ]; then + echo "Please pass a json file and a subscription type to this script." + echo "Valid subscription types include:" + echo " [UDP, TCP]" + echo "For example: $0 UDP subscribe_notify_test_one_event_two_eventgroups_udp_slave.json" + exit 1 +fi + +FAIL=0 + +export VSOMEIP_CONFIGURATION=$2 +# start daemon +../../examples/routingmanagerd/routingmanagerd & +PID_VSOMEIPD=$! + +# Start the services +./subscribe_notify_test_one_event_two_eventgroups_service $1 & +PID_SERVICE=$! + +# wait until service exits successfully +wait $PID_SERVICE || FAIL=$(($FAIL+1)) + + +# kill daemon +kill $PID_VSOMEIPD +wait $PID_VSOMEIPD || FAIL=$(($FAIL+1)) + +echo "" + +# Check if both exited successfully +if [ $FAIL -eq 0 ]; then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/subscribe_notify_tests/subscribe_notify_test_service.cpp b/test/network_tests/subscribe_notify_tests/subscribe_notify_test_service.cpp new file mode 100644 index 0000000..8e61757 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/subscribe_notify_test_service.cpp @@ -0,0 +1,514 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "subscribe_notify_test_globals.hpp" + + +class subscribe_notify_test_service { +public: + subscribe_notify_test_service(struct subscribe_notify_test::service_info _service_info, + std::array _service_infos, + vsomeip::reliability_type_e _reliability_type) : + service_info_(_service_info), + service_infos_(_service_infos), + app_(vsomeip::runtime::get()->create_application()), + wait_until_registered_(true), + wait_until_other_services_available_(true), + wait_until_notified_from_other_services_(true), + offer_thread_(std::bind(&subscribe_notify_test_service::run, this)), + wait_for_stop_(true), + stop_thread_(std::bind(&subscribe_notify_test_service::wait_for_stop, this)), + wait_for_notify_(true), + notify_thread_(std::bind(&subscribe_notify_test_service::notify, this)), + subscription_state_handler_called_(0), + subscription_error_occured_(false), + reliability_type_(_reliability_type) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + + app_->register_state_handler( + std::bind(&subscribe_notify_test_service::on_state, this, + std::placeholders::_1)); + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.method_id, + std::bind(&subscribe_notify_test_service::on_request, this, + std::placeholders::_1)); + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, + std::bind(&subscribe_notify_test_service::on_message, this, + std::placeholders::_1)); + + // offer event + std::set its_eventgroups; + its_eventgroups.insert(service_info_.eventgroup_id); + app_->offer_event(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_eventgroups, + vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), + false, true, nullptr, reliability_type_); + + + // register availability for all other services and request their event. + for(const auto& i : service_infos_) { + if ((i.service_id == service_info_.service_id + && i.instance_id == service_info_.instance_id) + || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { + continue; + } + app_->request_service(i.service_id, i.instance_id); + app_->register_availability_handler(i.service_id, i.instance_id, + std::bind(&subscribe_notify_test_service::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + + auto handler = std::bind(&subscribe_notify_test_service::on_subscription_state_change, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4, std::placeholders::_5); + app_->register_subscription_status_handler(i.service_id, i.instance_id, i.eventgroup_id, + vsomeip::ANY_EVENT, handler); + + + std::set its_eventgroups; + its_eventgroups.insert(i.eventgroup_id); + app_->request_event(i.service_id, i.instance_id, i.event_id, its_eventgroups, + vsomeip::event_type_e::ET_FIELD, reliability_type_); + + other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; + other_services_received_notification_[std::make_pair(i.service_id, i.method_id)] = 0; + } + + // register subscription handler to detect whether or not all other + // other services have subscribed + app_->register_subscription_handler(service_info_.service_id, + service_info_.instance_id, service_info_.eventgroup_id, + std::bind(&subscribe_notify_test_service::on_subscription, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3, std::placeholders::_4)); + + app_->start(); + } + + ~subscribe_notify_test_service() { + offer_thread_.join(); + stop_thread_.join(); + } + + void offer() { + app_->offer_service(service_info_.service_id, service_info_.instance_id); + } + + void stop_offer() { + app_->stop_offer_event(service_info_.service_id, service_info_.instance_id, service_info_.event_id); + app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + if(_is_available) { + auto its_service = other_services_available_.find(std::make_pair(_service, _instance)); + if(its_service != other_services_available_.end()) { + if(its_service->second != _is_available) { + its_service->second = true; + VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Service [" + << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance + << "] is available."; + + } + } + + if(std::all_of(other_services_available_.cbegin(), + other_services_available_.cend(), + [](const std::map, bool>::value_type& v) { + return v.second;})) { + std::lock_guard its_lock(mutex_); + wait_until_other_services_available_ = false; + condition_.notify_one(); + } + } + } + + void on_subscription_state_change(const vsomeip::service_t _service, const vsomeip::instance_t _instance, + const vsomeip::eventgroup_t _eventgroup, const vsomeip::event_t _event, const uint16_t _error) { + (void)_service; + (void)_instance; + (void)_eventgroup; + (void)_event; + + if (!_error) { + subscription_state_handler_called_++; + } else { + subscription_error_occured_ = true; + VSOMEIP_WARNING << std::hex << app_->get_client() + << " : on_subscription_state_change: for service " << std::hex + << _service << " received a subscription error!"; + } + } + + bool on_subscription(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, + bool _subscribed) { + (void)_uid; + (void)_gid; + std::lock_guard its_lock(subscribers_mutex_); + static bool notified(false); + if (_subscribed) { + subscribers_.insert(_client); + } else { + subscribers_.erase(_client); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] " << "Client: " + << std::setw(4) << std::setfill('0') << std::hex << _client + << (_subscribed ? " subscribed" : " unsubscribed") + << ", now have " << std::dec << subscribers_.size() + << " subscribers" ; + // check if all other services have subscribed: + // -1 for placeholder in array + // divide by two because we only receive once subscription per remote node + // no matter how many clients subscribed to this eventgroup on the remote node + if (!notified && subscribers_.size() == (service_infos_.size() - 1) / 2 ) + { + // notify the notify thread to start sending out notifications + std::lock_guard its_lock(notify_mutex_); + wait_for_notify_ = false; + notify_condition_.notify_one(); + notified = true; + } + return true; + } + + void on_request(const std::shared_ptr &_message) { + if(_message->get_message_type() == vsomeip::message_type_e::MT_REQUEST) { + VSOMEIP_DEBUG << "Received a request with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_session() << "]"; + std::shared_ptr its_response = vsomeip::runtime::get() + ->create_response(_message); + app_->send(its_response); + } + } + + void on_message(const std::shared_ptr &_message) { + if(_message->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { + + other_services_received_notification_[std::make_pair(_message->get_service(), + _message->get_method())]++; + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] " + << "Received a notification with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _message->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_session() << "] from Service/Method [" + << std::setw(4) << std::setfill('0') << std::hex + << _message->get_service() << "/" << std::setw(4) << std::setfill('0') + << std::hex << _message->get_method() << "/" << std::dec << _message->get_length() << "] (now have: " + << std::dec << other_services_received_notification_[std::make_pair(_message->get_service(), + _message->get_method())] << ")"; + + if(all_notifications_received()) { + std::lock_guard its_lock(stop_mutex_); + wait_for_stop_ = false; + stop_condition_.notify_one(); + } + } + } + + bool all_notifications_received() { + return std::all_of( + other_services_received_notification_.cbegin(), + other_services_received_notification_.cend(), + [&](const std::map, std::uint32_t>::value_type& v) + { + return v.second == subscribe_notify_test::notifications_to_send; + } + ); + } + + bool all_notifications_received_tcp_and_udp() { + std::uint32_t received_twice(0); + std::uint32_t received_normal(0); + for(const auto &v : other_services_received_notification_) { + if (v.second == subscribe_notify_test::notifications_to_send * 2) { + received_twice++; + } else if(v.second == subscribe_notify_test::notifications_to_send) { + received_normal++; + } + } + + if( received_twice == (service_infos_.size() - 1) / 2 + && received_normal == (service_infos_.size() - 1) / 2 - 1) { + // routing manager stub receives the notification + // - twice from external nodes + // - and normal from all internal nodes + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] " + << "Received notifications:" + << " Normal: " << received_normal + << " Twice: " << received_twice; + return true; + } + return false; + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + std::unique_lock its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + + + while (wait_until_other_services_available_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Subscribing"; + // subscribe to events of other services + uint32_t subscribe_count = 0; + for(const subscribe_notify_test::service_info& i: service_infos_) { + if ((i.service_id == service_info_.service_id + && i.instance_id == service_info_.instance_id) + || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { + continue; + } + ++subscribe_count; + app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, + vsomeip::DEFAULT_MAJOR); + VSOMEIP_DEBUG << "[" << std::hex << service_info_.service_id + << "] subscribing to Service/Instance/Eventgroup [" + << std::setw(4) << std::setfill('0') << std::hex << i.service_id << "/" + << std::setw(4) << std::setfill('0') << std::hex << i.instance_id + << "/" << std::setw(4) << std::setfill('0') << std::hex << i.eventgroup_id <<"]"; + } + + while (wait_until_notified_from_other_services_) { + condition_.wait(its_lock); + } + + // It is possible that we run in the case a subscription is NACKED + // due to TCP endpoint not completely connected when subscription + // is processed in the server - due to resubscribing the error handler + // count may differ from expected value, but its not a real but as + // the subscription takes places anyways and all events will be received. + if (!subscription_error_occured_) { + ASSERT_EQ(subscribe_count, subscription_state_handler_called_); + } else { + VSOMEIP_WARNING << "Subscription state handler check skipped: CallCount=" + << std::dec << subscription_state_handler_called_; + } + } + + void notify() { + std::unique_lock its_lock(notify_mutex_); + while (wait_for_notify_) { + notify_condition_.wait(its_lock); + } + + // sleep a while before starting to notify this is necessary as it's not + // possible to detect if _all_ clients on the remote side have + // successfully subscribed as we only receive once subscription per + // remote node no matter how many clients subscribed to this eventgroup + // on the remote node + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Starting to notify"; + + for(uint32_t i = 0; i < subscribe_notify_test::notifications_to_send; i++) { + std::shared_ptr its_payload = + vsomeip::runtime::get()->create_payload(); + + vsomeip::byte_t its_data[10] = {0}; + for (uint32_t j = 0; j < i+1; ++j) { + its_data[j] = static_cast(j); + } + its_payload->set_data(its_data, i+1); + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Notifying: " << i+1; + app_->notify(service_info_.service_id, service_info_.instance_id, + service_info_.event_id, its_payload); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } + + void wait_for_stop() { + std::unique_lock its_lock(stop_mutex_); + while (wait_for_stop_) { + stop_condition_.wait(its_lock); + } + + // wait until all notifications have been sent out + notify_thread_.join(); + + VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id + << "] Received notifications from all other services, going down"; + + // let offer thread exit + { + std::lock_guard its_lock(mutex_); + wait_until_notified_from_other_services_ = false; + condition_.notify_one(); + } + + stop_offer(); + + // ensure that the service which hosts the routing doesn't exit to early + if (app_->is_routing()) { + for (const auto& i : service_infos_) { + if ((i.service_id == service_info_.service_id + && i.instance_id == service_info_.instance_id) + || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { + continue; + } + while (app_->is_available(i.service_id, i.instance_id, + vsomeip::ANY_MAJOR, vsomeip::ANY_MINOR)) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + } + } + + std::this_thread::sleep_for(std::chrono::seconds(1)); + for(const auto& i : service_infos_) { + if ((i.service_id == service_info_.service_id + && i.instance_id == service_info_.instance_id) + || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { + continue; + } + app_->unregister_subscription_status_handler(i.service_id, i.instance_id, + i.eventgroup_id, vsomeip::ANY_EVENT); + app_->unsubscribe(i.service_id, i.instance_id, i.eventgroup_id); + app_->release_event(i.service_id, i.instance_id, i.event_id); + app_->release_service(i.service_id, i.instance_id); + } + app_->clear_all_handler(); + app_->stop(); + } + +private: + subscribe_notify_test::service_info service_info_; + std::array service_infos_; + std::shared_ptr app_; + std::map, bool> other_services_available_; + std::map, std::uint32_t> other_services_received_notification_; + + bool wait_until_registered_; + bool wait_until_other_services_available_; + bool wait_until_notified_from_other_services_; + std::mutex mutex_; + std::condition_variable condition_; + std::thread offer_thread_; + + bool wait_for_stop_; + std::mutex stop_mutex_; + std::condition_variable stop_condition_; + std::thread stop_thread_; + + std::set subscribers_; + bool wait_for_notify_; + std::mutex notify_mutex_; + std::condition_variable notify_condition_; + std::thread notify_thread_; + std::atomic subscription_state_handler_called_; + std::atomic subscription_error_occured_; + + std::mutex subscribers_mutex_; + vsomeip::reliability_type_e reliability_type_; +}; + +static unsigned long service_number; +static bool use_same_service_id; +vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN; + + +TEST(someip_subscribe_notify_test, send_ten_notifications_to_service) +{ + if(use_same_service_id) { + subscribe_notify_test_service its_sample( + subscribe_notify_test::service_infos_same_service_id[service_number], + subscribe_notify_test::service_infos_same_service_id, + reliability_type); + } else { + subscribe_notify_test_service its_sample( + subscribe_notify_test::service_infos[service_number], + subscribe_notify_test::service_infos, + reliability_type); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a service number and event reliability type, like: " << argv[0] << " 2 UDP SAME_SERVICE_ID" << std::endl; + std::cerr << "Valid service numbers are in the range of [1,6]" << std::endl; + std::cerr << "Valid event reliability types are [UDP, TCP, TCP_AND_UDP]" << std::endl; + std::cerr << "If SAME_SERVICE_ID is specified as third parameter the test is run w/ multiple instances of the same service" << std::endl; + return 1; + } + + service_number = std::stoul(std::string(argv[1]), nullptr); + + if (argc >= 3) { + if (std::string("TCP")== std::string(argv[2])) { + reliability_type = vsomeip::reliability_type_e::RT_RELIABLE; + } else if (std::string("UDP")== std::string(argv[2])) { + reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE; + } else if (std::string("TCP_AND_UDP")== std::string(argv[2])) { + reliability_type = vsomeip::reliability_type_e::RT_BOTH; + } + } + + if (argc >= 4 && std::string("SAME_SERVICE_ID") == std::string(argv[3])) { + use_same_service_id = true; + } else { + use_same_service_id = false; + } + + + + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh b/test/network_tests/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh new file mode 100755 index 0000000..8133161 --- /dev/null +++ b/test/network_tests/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +if [ $# -lt 1 ] +then + echo "Please pass a json file to this script." + echo "For example: $0 UDP subscribe_notify_test_diff_client_ids_diff_ports_slave.json" + echo "To use the same service id but different instances on the node pass SAME_SERVICE_ID as third parameter" + exit 1 +fi + +RELIABILITY_TYPE=$1 +SLAVE_JSON_FILE=$2 +SAME_SERVICE_ID=$3 + +FAIL=0 +# Start the services +export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_four +export VSOMEIP_CONFIGURATION=$SLAVE_JSON_FILE +./subscribe_notify_test_service 4 $RELIABILITY_TYPE $3 & + +export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_five +export VSOMEIP_CONFIGURATION=$SLAVE_JSON_FILE +./subscribe_notify_test_service 5 $RELIABILITY_TYPE $3 & + +export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_six +export VSOMEIP_CONFIGURATION=$SLAVE_JSON_FILE +./subscribe_notify_test_service 6 $RELIABILITY_TYPE $3 & + +sleep 3 + +# Wait until all applications are finished +for job in $(jobs -p) +do + # Fail gets incremented if one of the binaries exits + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +# Check if both exited successfully +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/suspend_resume_tests/conf/suspend_resume_test_client.json.in b/test/network_tests/suspend_resume_tests/conf/suspend_resume_test_client.json.in new file mode 100644 index 0000000..db94cea --- /dev/null +++ b/test/network_tests/suspend_resume_tests/conf/suspend_resume_test_client.json.in @@ -0,0 +1,32 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : { "enable" : "false", "path" : "" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "suspend_resume_test_client", + "id" : "0x4567" + } + ], + "routing" : "suspend_resume_test_client", + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/suspend_resume_tests/conf/suspend_resume_test_service.json.in b/test/network_tests/suspend_resume_tests/conf/suspend_resume_test_service.json.in new file mode 100644 index 0000000..44b510b --- /dev/null +++ b/test/network_tests/suspend_resume_tests/conf/suspend_resume_test_service.json.in @@ -0,0 +1,40 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : { "enable" : "false", "path" : "" }, + "dlt" : "false" + }, + "applications" : + [ + { + "name" : "suspend_resume_test_service", + "id" : "0x7654" + } + ], + "services" : + [ + { + "service" : "0x6311", + "instance" : "0x0002", + "unreliable" : "34504" + } + ], + "routing" : "routingmanagerd", + "service-discovery" : + { + "enable" : "true", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} \ No newline at end of file diff --git a/test/network_tests/suspend_resume_tests/suspend_resume_test.hpp b/test/network_tests/suspend_resume_tests/suspend_resume_test.hpp new file mode 100644 index 0000000..5271bba --- /dev/null +++ b/test/network_tests/suspend_resume_tests/suspend_resume_test.hpp @@ -0,0 +1,22 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef SUSPEND_RESUME_TEST_ +#define SUSPEND_RESUME_TEST_ + +#define TEST_SERVICE 0x6311 +#define TEST_INSTANCE 0x0002 +#define TEST_MAJOR 0x01 +#define TEST_MINOR 0x0 + +#define TEST_EVENT 0x8005 +#define TEST_EVENTGROUP 0x0002 + +#define TEST_METHOD 0x0001 + +#define TEST_SUSPEND 0x00 +#define TEST_STOP 0xFF + +#endif // SUSPEND_RESUME_TEST_ diff --git a/test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp b/test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp new file mode 100644 index 0000000..11ae578 --- /dev/null +++ b/test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp @@ -0,0 +1,239 @@ +// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include + +#include + +#include +#include + +#include "suspend_resume_test.hpp" + +class suspend_resume_test_client { +public: + suspend_resume_test_client() + : name_("suspend_resume_test_client"), + app_(vsomeip::runtime::get()->create_application(name_)), + has_received_(false), + runner_(std::bind(&suspend_resume_test_client::run, this)) { + + } + + void run_test() { + + register_state_handler(); + register_message_handler(); + register_availability_handler(); + + start(); + + { + VSOMEIP_DEBUG << "Started."; + std::unique_lock its_lock(mutex_); + auto r = cv_.wait_for(its_lock, std::chrono::seconds(10)); + EXPECT_EQ(r, std::cv_status::no_timeout); + } + + toggle(); + + { + VSOMEIP_DEBUG << "Toggled."; + std::unique_lock its_lock(mutex_); + if (!has_received_) { + auto r = cv_.wait_for(its_lock, std::chrono::seconds(10)); + EXPECT_EQ(r, std::cv_status::no_timeout); + } + } + + send_suspend(); + + bool was_successful; + { + VSOMEIP_DEBUG << "Triggered suspend/resume."; + + // Wait for service to become availaber after suspend/resume. + std::unique_lock its_lock(mutex_); + auto r = cv_.wait_for(its_lock, std::chrono::seconds(10)); + EXPECT_EQ(r, std::cv_status::no_timeout); + + // Wait for initial event after suspend/resume. + r = cv_.wait_for(its_lock, std::chrono::seconds(10)); + EXPECT_EQ(r, std::cv_status::no_timeout); + + was_successful = (r == std::cv_status::no_timeout); + } + + if (was_successful) + send_stop(); + + stop(); + } + +private: + void register_state_handler() { + + app_->register_state_handler( + std::bind(&suspend_resume_test_client::on_state, this, std::placeholders::_1)); + } + + void register_availability_handler() { + + app_->register_availability_handler(TEST_SERVICE, TEST_INSTANCE, + std::bind(&suspend_resume_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + } + + void register_message_handler() { + + app_->register_message_handler(TEST_SERVICE, TEST_INSTANCE, TEST_EVENT, + std::bind(&suspend_resume_test_client::on_message, this, + std::placeholders::_1)); + } + + void start() { + + app_->init(); + cv_.notify_one(); + } + + void run() { + + { + std::unique_lock its_lock(mutex_); + cv_.wait(its_lock); + } + + app_->start(); + } + + void stop() { + + app_->stop(); + runner_.join(); + } + + void on_state(vsomeip::state_type_e _state) { + + VSOMEIP_DEBUG << __func__ << ": state=" + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "NOT registered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + app_->request_event(TEST_SERVICE, TEST_INSTANCE, TEST_EVENT, { TEST_EVENTGROUP }); + app_->request_service(TEST_SERVICE, TEST_INSTANCE); + } + } + + void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) { + + static bool is_available(false); + + if (_service == TEST_SERVICE && _instance == TEST_INSTANCE) { + + VSOMEIP_DEBUG << __func__ << ": Test service is " + << (_is_available ? "available." : "NOT available."); + + if (_is_available) + cv_.notify_one(); + else if (is_available) + has_received_ = false; + + is_available = _is_available; + } + } + + void on_message(const std::shared_ptr &_message) { + + if (_message->get_service() == TEST_SERVICE + && _message->get_instance() == TEST_INSTANCE + && _message->get_method() == TEST_EVENT) { + + VSOMEIP_DEBUG << __func__ << ": Received event."; + if (!has_received_) { + has_received_ = true; + cv_.notify_one(); + } + } + } + + void toggle() { + + app_->subscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, TEST_MAJOR); + std::this_thread::sleep_for(std::chrono::seconds(3)); + app_->unsubscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP); + app_->subscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, TEST_MAJOR); + std::this_thread::sleep_for(std::chrono::seconds(2)); + app_->unsubscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP); + app_->subscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, TEST_MAJOR); + + } + + + void send_suspend() { + + auto its_message = vsomeip::runtime::get()->create_request(false); + its_message->set_service(TEST_SERVICE); + its_message->set_instance(TEST_INSTANCE); + its_message->set_method(TEST_METHOD); + its_message->set_interface_version(TEST_MAJOR); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + its_message->set_return_code(vsomeip::return_code_e::E_OK); + + vsomeip::byte_t its_data[] = { TEST_SUSPEND }; + auto its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data(its_data, sizeof(its_data)); + its_message->set_payload(its_payload); + + app_->send(its_message); + + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + + void send_stop() { + + auto its_message = vsomeip::runtime::get()->create_request(false); + its_message->set_service(TEST_SERVICE); + its_message->set_instance(TEST_INSTANCE); + its_message->set_method(TEST_METHOD); + its_message->set_interface_version(TEST_MAJOR); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + its_message->set_return_code(vsomeip::return_code_e::E_OK); + + vsomeip::byte_t its_data[] = { TEST_STOP }; + auto its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data(its_data, sizeof(its_data)); + its_message->set_payload(its_payload); + + app_->send(its_message); + + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + +private: // members + std::string name_; + std::shared_ptr app_; + std::mutex mutex_; + std::condition_variable cv_; + bool has_received_; + std::thread runner_; +}; + +TEST(suspend_resume_test, fast) +{ + suspend_resume_test_client its_client; + its_client.run_test(); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) { + + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/suspend_resume_tests/suspend_resume_test_master_starter.sh b/test/network_tests/suspend_resume_tests/suspend_resume_test_master_starter.sh new file mode 100755 index 0000000..44b1b74 --- /dev/null +++ b/test/network_tests/suspend_resume_tests/suspend_resume_test_master_starter.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +FAIL=0 + +# Start the service +export VSOMEIP_APPLICATION_NAME=suspend_resume_test_service +export VSOMEIP_CONFIGURATION=suspend_resume_test_service.json + +# start daemon +../../examples/routingmanagerd/./routingmanagerd & +PID_VSOMEIPD=$! + +# start the service +./suspend_resume_test_service $PID_VSOMEIPD & +PID_SERVICE=$! + +sleep 1 + +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting suspend_resume_test_slave_starter.sh on slave LXC with parameters $SLAVE_JSON_FILE" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./suspend_resume_test_slave_starter.sh\"" & + echo "remote ssh job id: $!" +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./suspend_resume_test_slave_starter.sh" & +else + cat < +#include +#include +#include + +#include + +#include +#include + +#include "suspend_resume_test.hpp" + +pid_t daemon_pid__; + +class suspend_resume_test_service { +public: + suspend_resume_test_service() + : name_("suspend_resume_test_service"), + app_(vsomeip::runtime::get()->create_application(name_)), + is_running_(true), + is_unblocked_(false), + runner_(std::bind(&suspend_resume_test_service::run, this)), + sr_runner_(std::bind(&suspend_resume_test_service::sr_run, this)) { + } + + void run_test() { + + register_state_handler(); + register_message_handler(); + register_subscription_handler(); + + start(); + + VSOMEIP_DEBUG << "Using daemon with pid=" << std::dec << daemon_pid__; + + { + std::unique_lock its_lock(mutex_); + auto r = cv_.wait_for(its_lock, std::chrono::seconds(30)); + EXPECT_EQ(r, std::cv_status::no_timeout); + } + + stop(); + } + +private: + void start() { + + app_->init(); + cv_.notify_one(); + } + + void stop() { + + is_running_ = false; + sr_cv_.notify_one(); + + app_->stop(); + + runner_.join(); + sr_runner_.join(); + } + + void run() { + + { + std::unique_lock its_lock(mutex_); + cv_.wait(its_lock); + } + + app_->start(); + } + + void sr_run() { + + while (is_running_) { + std::unique_lock its_lock(sr_mutex_); + sr_cv_.wait(its_lock); + + if (is_running_) { + VSOMEIP_DEBUG << "send kill SIGUSR1 to PID: " << std::dec << daemon_pid__; + kill(daemon_pid__, SIGUSR1); + std::this_thread::sleep_for(std::chrono::seconds(5)); + VSOMEIP_DEBUG << "send kill SIGUSR2 to PID: " << std::dec << daemon_pid__; + kill(daemon_pid__, SIGUSR2); + } + } + } + + void register_state_handler() { + + app_->register_state_handler( + std::bind(&suspend_resume_test_service::on_state, this, std::placeholders::_1)); + } + + void register_message_handler() { + + app_->register_message_handler(TEST_SERVICE, TEST_INSTANCE, TEST_METHOD, + std::bind(&suspend_resume_test_service::on_message, this, + std::placeholders::_1)); + } + + void register_subscription_handler() { + + app_->register_subscription_handler(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, + std::bind(&suspend_resume_test_service::on_subscribe, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); + } + + void offer_service() { + app_->offer_event(TEST_SERVICE, TEST_INSTANCE, TEST_EVENT, { TEST_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), false, true, nullptr, + vsomeip::reliability_type_e::RT_UNRELIABLE); + + vsomeip::byte_t its_data[] = { 0x1, 0x2, 0x3 }; + auto its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data(its_data, sizeof(its_data)); + app_->notify(TEST_SERVICE, TEST_INSTANCE, TEST_EVENT, its_payload); + + app_->offer_service(TEST_SERVICE, TEST_INSTANCE, TEST_MAJOR, TEST_MINOR); + } + + // handler + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_DEBUG << __func__ << ": state=" + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "NOT registered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + offer_service(); + } + } + + void on_message(const std::shared_ptr &_message) { + + VSOMEIP_DEBUG << __func__ << ": Received " + << std::hex << std::setw(4) << std::setfill('0') + << _message->get_service() + << std::hex << std::setw(4) << std::setfill('0') + << _message->get_instance() + << std::hex << std::setw(4) << std::setfill('0') + << _message->get_method(); + + if (_message->get_service() == TEST_SERVICE + && _message->get_instance() == TEST_INSTANCE + && _message->get_method() == TEST_METHOD) { + + if (_message->get_payload()->get_length() == 1) { + + vsomeip::byte_t its_control_byte(*_message->get_payload()->get_data()); + + switch (its_control_byte) { + case TEST_SUSPEND: + sr_cv_.notify_one(); + break; + case TEST_STOP: + cv_.notify_one(); + break; + default: + ; + } + } + } + } + + bool on_subscribe(vsomeip::client_t _client, + vsomeip::uid_t _uid, vsomeip::gid_t _gid, + bool _is_subscribe) { + + (void)_client; + (void)_uid; + (void)_gid; + + VSOMEIP_DEBUG << __func__ << ": is_subscribe=" << std::boolalpha << _is_subscribe; + if (!_is_subscribe) + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + return (true); + } + +private: // members + std::string name_; + std::shared_ptr app_; + std::atomic is_running_; + bool is_unblocked_; + std::mutex mutex_; + std::condition_variable cv_; + std::mutex sr_mutex_; + std::condition_variable sr_cv_; + std::thread runner_; + std::thread sr_runner_; +}; + +TEST(suspend_resume_test, fast) +{ + suspend_resume_test_service its_service; + its_service.run_test(); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) { + + ::testing::InitGoogleTest(&argc, argv); + + daemon_pid__ = atoi(argv[1]); + + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/suspend_resume_tests/suspend_resume_test_slave_starter.sh b/test/network_tests/suspend_resume_tests/suspend_resume_test_slave_starter.sh new file mode 100755 index 0000000..9cbf85d --- /dev/null +++ b/test/network_tests/suspend_resume_tests/suspend_resume_test_slave_starter.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +FAIL=0 + +# Start the client +export VSOMEIP_APPLICATION_NAME=suspend_resume_test_client +export VSOMEIP_CONFIGURATION=suspend_resume_test_client.json +./suspend_resume_test_client & +PID_CLIENT=$! + +# Wait until all applications are finished +for job in $(jobs -p) +do + # Fail gets incremented if one of the binaries exits + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +# Check if both exited successfully +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi \ No newline at end of file diff --git a/test/npdu_tests/conf/npdu_test_client_no_npdu.json.in b/test/npdu_tests/conf/npdu_test_client_no_npdu.json.in deleted file mode 100644 index 07cfe08..0000000 --- a/test/npdu_tests/conf/npdu_test_client_no_npdu.json.in +++ /dev/null @@ -1,39 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"info", - "console":"true" - }, - "applications": - [ - { - "name":"npdu_test_routing_manager_daemon_client_side", - "id":"0x6666" - }, - { - "name":"npdu_test_client_one", - "id":"0x1111" - }, - { - "name":"npdu_test_client_two", - "id":"0x2222" - }, - { - "name":"npdu_test_client_three", - "id":"0x3333" - }, - { - "name":"npdu_test_client_four", - "id":"0x4444" - } - ], - "routing":"npdu_test_routing_manager_daemon_client_side", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/npdu_tests/conf/npdu_test_client_npdu.json.in b/test/npdu_tests/conf/npdu_test_client_npdu.json.in deleted file mode 100644 index dc35023..0000000 --- a/test/npdu_tests/conf/npdu_test_client_npdu.json.in +++ /dev/null @@ -1,167 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"info", - "console":"true" - }, - "applications": - [ - { - "name":"npdu_test_routing_manager_daemon_client_side", - "id":"0x6666" - }, - { - "name":"npdu_test_client_one", - "id":"0x1111" - }, - { - "name":"npdu_test_client_two", - "id":"0x2222" - }, - { - "name":"npdu_test_client_three", - "id":"0x3333" - }, - { - "name":"npdu_test_client_four", - "id":"0x4444" - } - ], - "services": - [ - { - "service":"0x1000", - "instance":"0x0001", - "unicast":"@TEST_IP_MASTER@", - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - }, - "debounce-times": - { - "requests" : { - "0x1001" : { - "debounce-time" : "10", - "maximum-retention-time" : "100" - }, - "0x1002" : { - "debounce-time" : "20", - "maximum-retention-time" : "200" - }, - "0x1003" : { - "debounce-time" : "30", - "maximum-retention-time" : "300" - }, - "0x1004" : { - "debounce-time" : "40", - "maximum-retention-time" : "400" - } - } - } - }, - { - "service":"0x2000", - "instance":"0x0002", - "unicast":"@TEST_IP_MASTER@", - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - }, - "debounce-times" : { - "requests" : { - "0x2001" : { - "debounce-time" : "10", - "maximum-retention-time" : "100" - }, - "0x2002" : { - "debounce-time" : "20", - "maximum-retention-time" : "200" - }, - "0x2003" : { - "debounce-time" : "30", - "maximum-retention-time" : "300" - }, - "0x2004" : { - "debounce-time" : "40", - "maximum-retention-time" : "400" - } - } - } - }, - { - "service":"0x3000", - "instance":"0x0003", - "unicast":"@TEST_IP_MASTER@", - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - }, - "debounce-times" : { - "requests" : { - "0x3001" : { - "debounce-time" : "10", - "maximum-retention-time" : "100" - }, - "0x3002" : { - "debounce-time" : "20", - "maximum-retention-time" : "200" - }, - "0x3003" : { - "debounce-time" : "30", - "maximum-retention-time" : "300" - }, - "0x3004" : { - "debounce-time" : "40", - "maximum-retention-time" : "400" - } - } - } - }, - { - "service":"0x4000", - "instance":"0x0004", - "unicast":"@TEST_IP_MASTER@", - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - }, - "debounce-times": { - "requests" : { - "0x4001" : { - "debounce-time" : "10", - "maximum-retention-time" : "100" - }, - "0x4002" : { - "debounce-time" : "20", - "maximum-retention-time" : "200" - }, - "0x4003" : { - "debounce-time" : "30", - "maximum-retention-time" : "300" - }, - "0x4004" : { - "debounce-time" : "40", - "maximum-retention-time" : "400" - } - } - } - } - ], - "routing":"npdu_test_routing_manager_daemon_client_side", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/npdu_tests/conf/npdu_test_service_no_npdu.json.in b/test/npdu_tests/conf/npdu_test_service_no_npdu.json.in deleted file mode 100644 index b4c8eaa..0000000 --- a/test/npdu_tests/conf/npdu_test_service_no_npdu.json.in +++ /dev/null @@ -1,87 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"info", - "console":"true" - }, - "applications": - [ - { - "name":"npdu_test_routing_manager_daemon_service_side", - "id":"0x6667" - }, - { - "name":"npdu_test_service_one", - "id":"0x1000" - }, - { - "name":"npdu_test_service_two", - "id":"0x2000" - }, - { - "name":"npdu_test_service_three", - "id":"0x3000" - }, - { - "name":"npdu_test_service_four", - "id":"0x4000" - } - ], - "services": - [ - { - "service":"0x6667", - "instance":"0x6666", - "unreliable":"60666" - }, - { - "service":"0x1000", - "instance":"0x0001", - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2000", - "instance":"0x0002", - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3000", - "instance":"0x0003", - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x4000", - "instance":"0x0004", - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - } - } - ], - "routing":"npdu_test_routing_manager_daemon_service_side", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/npdu_tests/conf/npdu_test_service_npdu.json.in b/test/npdu_tests/conf/npdu_test_service_npdu.json.in deleted file mode 100644 index 0de75cf..0000000 --- a/test/npdu_tests/conf/npdu_test_service_npdu.json.in +++ /dev/null @@ -1,168 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"info", - "console":"true" - }, - "applications": - [ - { - "name":"npdu_test_routing_manager_daemon_service_side", - "id":"0x6667" - }, - { - "name":"npdu_test_service_one", - "id":"0x1000" - }, - { - "name":"npdu_test_service_two", - "id":"0x2000" - }, - { - "name":"npdu_test_service_three", - "id":"0x3000" - }, - { - "name":"npdu_test_service_four", - "id":"0x4000" - } - ], - "services": - [ - { - "service":"0x6667", - "instance":"0x6666", - "unreliable":"60666" - }, - { - "service":"0x1000", - "instance":"0x0001", - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - }, - "debounce-times": - { - "responses" : { - "0x1001" : { - "debounce-time" : "10", - "maximum-retention-time" : "100" - }, - "0x1002" : { - "debounce-time" : "20", - "maximum-retention-time" : "200" - }, - "0x1003" : { - "debounce-time" : "30", - "maximum-retention-time" : "300" - }, - "0x1004" : { - "debounce-time" : "40", - "maximum-retention-time" : "400" - } - } - } - }, - { - "service":"0x2000", - "instance":"0x0002", - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - }, - "debounce-times" : { - "responses" : { - "0x2001" : { - "debounce-time" : "10", - "maximum-retention-time" : "100" - }, - "0x2002" : { - "debounce-time" : "20", - "maximum-retention-time" : "200" - }, - "0x2003" : { - "debounce-time" : "30", - "maximum-retention-time" : "300" - }, - "0x2004" : { - "debounce-time" : "40", - "maximum-retention-time" : "400" - } - } - } - }, - { - "service":"0x3000", - "instance":"0x0003", - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - }, - "debounce-times" : { - "responses" : { - "0x3001" : { - "debounce-time" : "10", - "maximum-retention-time" : "100" - }, - "0x3002" : { - "debounce-time" : "20", - "maximum-retention-time" : "200" - }, - "0x3003" : { - "debounce-time" : "30", - "maximum-retention-time" : "300" - }, - "0x3004" : { - "debounce-time" : "40", - "maximum-retention-time" : "400" - } - } - } - }, - { - "service":"0x4000", - "instance":"0x0004", - "unreliable":"30509", - "reliable": - { - "port":"30510", - "enable-magic-cookies":"false" - }, - "debounce-times": { - "responses" : { - "0x4001" : { - "debounce-time" : "10", - "maximum-retention-time" : "100" - }, - "0x4002" : { - "debounce-time" : "20", - "maximum-retention-time" : "200" - }, - "0x4003" : { - "debounce-time" : "30", - "maximum-retention-time" : "300" - }, - "0x4004" : { - "debounce-time" : "40", - "maximum-retention-time" : "400" - } - } - } - } - ], - "routing":"npdu_test_routing_manager_daemon_service_side", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp" - } -} diff --git a/test/npdu_tests/npdu_test_client.cpp b/test/npdu_tests/npdu_test_client.cpp deleted file mode 100644 index ca29aa6..0000000 --- a/test/npdu_tests/npdu_test_client.cpp +++ /dev/null @@ -1,599 +0,0 @@ -// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. -#include "../npdu_tests/npdu_test_client.hpp" - -#include -#include "../../implementation/configuration/include/configuration.hpp" -#include "../../implementation/configuration/include/configuration_impl.hpp" -#include "../../implementation/configuration/include/configuration_plugin.hpp" -#include "../../implementation/plugin/include/plugin_manager_impl.hpp" - -enum class payloadsize - : std::uint8_t - { - UDS, TCP, UDP -}; - -// this variables are changed via cmdline parameters -static bool use_tcp = false; -static bool call_service_sync = true; -static bool wait_for_replies = true; -static std::uint32_t sliding_window_size = vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND; -static payloadsize max_payload_size = payloadsize::UDS; -static bool shutdown_service_at_end = true; - -npdu_test_client::npdu_test_client( - bool _use_tcp, - bool _call_service_sync, - std::uint32_t _sliding_window_size, - bool _wait_for_replies, - std::array, 4> _applicative_debounce) : - app_(vsomeip::runtime::get()->create_application()), - request_(vsomeip::runtime::get()->create_request(_use_tcp)), - call_service_sync_(_call_service_sync), - wait_for_replies_(_wait_for_replies), - sliding_window_size_(_sliding_window_size), - blocked_({false}), - is_available_({false}), // will set first element to false, rest to 0 - number_of_messages_to_send_(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND), - number_of_sent_messages_{0,0,0,0}, - number_of_acknowledged_messages_{{{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}}}, - current_payload_size_({0}), - all_msg_acknowledged_({false, false, false, false}), - acknowledgements_{0,0,0,0}, - applicative_debounce_(_applicative_debounce), - finished_waiter_(&npdu_test_client::wait_for_all_senders, this) -{ - senders_[0] = std::thread(&npdu_test_client::run<0>, this); - senders_[1] = std::thread(&npdu_test_client::run<1>, this); - senders_[2] = std::thread(&npdu_test_client::run<2>, this); - senders_[3] = std::thread(&npdu_test_client::run<3>, this); -} - -npdu_test_client::~npdu_test_client() { - finished_waiter_.join(); -} - -void npdu_test_client::init() -{ - app_->init(); - - app_->register_state_handler( - std::bind(&npdu_test_client::on_state, this, - std::placeholders::_1)); - - register_availability_handler<0>(); - register_availability_handler<1>(); - register_availability_handler<2>(); - register_availability_handler<3>(); - - register_message_handler_for_all_service_methods<0>(); - register_message_handler_for_all_service_methods<1>(); - register_message_handler_for_all_service_methods<2>(); - register_message_handler_for_all_service_methods<3>(); - - request_->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - request_->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - if(!wait_for_replies_) - request_->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); -} - -template -void npdu_test_client::register_availability_handler() { - app_->register_availability_handler(npdu_test::service_ids[service_idx], - npdu_test::instance_ids[service_idx], - std::bind( - &npdu_test_client::on_availability, - this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); -} - -template -void npdu_test_client::register_message_handler_for_all_service_methods() { - register_message_handler(); - register_message_handler(); - register_message_handler(); - register_message_handler(); -} - -template -void npdu_test_client::register_message_handler() { - app_->register_message_handler(npdu_test::service_ids[service_idx], - npdu_test::instance_ids[service_idx], - npdu_test::method_ids[service_idx][method_idx], - std::bind( - &npdu_test_client::on_message, - this, std::placeholders::_1)); -} - -void npdu_test_client::start() -{ - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void npdu_test_client::stop() -{ - VSOMEIP_INFO << "Stopping..."; - - app_->unregister_state_handler(); - - for (unsigned int i = 0; i< npdu_test::service_ids.size(); i++) { - app_->unregister_availability_handler(npdu_test::service_ids[i], - npdu_test::instance_ids[i]); - - for(unsigned int j = 0; j < npdu_test::method_ids[i].size(); j++) { - app_->unregister_message_handler(npdu_test::service_ids[i], - npdu_test::instance_ids[i], - npdu_test::method_ids[i][j]); - } - } - - if(shutdown_service_at_end) { - // notify the routing manager daemon that were finished - request_->set_service(npdu_test::RMD_SERVICE_ID_CLIENT_SIDE); - request_->set_instance(npdu_test::RMD_INSTANCE_ID); - request_->set_method(npdu_test::RMD_SHUTDOWN_METHOD_ID); - request_->set_payload(vsomeip::runtime::get()->create_payload()); - request_->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); - app_->send(request_); - // sleep otherwise the app will shutdown before the message reaches the rmd - std::this_thread::sleep_for(std::chrono::seconds(5)); - } - app_->stop(); -} - -void npdu_test_client::join_sender_thread() { - for (auto& t : senders_) { - t.join(); - } -} - -void npdu_test_client::on_state(vsomeip::state_type_e _state) -{ - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - for (unsigned int i = 0; i< npdu_test::service_ids.size(); i++) { - app_->request_service(npdu_test::service_ids[i], - npdu_test::instance_ids[i]); - } - } -} - -template -void npdu_test_client::on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) -{ - VSOMEIP_INFO<< "Service [" << std::setw(4) << std::setfill('0') << std::hex - << _service << "." << std::setw(4) << std::setfill('0') << _instance << "] is " - << (_is_available ? "available." : "NOT available."); - if(npdu_test::service_ids[service_idx] == _service - && npdu_test::instance_ids[service_idx] == _instance) { - if(is_available_[service_idx] && !_is_available) - { - is_available_[service_idx] = false; - } - else if(_is_available && !is_available_[service_idx]) - { - is_available_[service_idx] = true; - send(); - } - } -} - -template -void npdu_test_client::on_message(const std::shared_ptr& _response) { - (void)_response; - //TODO make sure the replies were sent within demanded debounce times - VSOMEIP_DEBUG << "Received reply from:" << std::setw(4) << std::setfill('0') - << std::hex << npdu_test::service_ids[service_idx] << ":" - << std::setw(4) << std::setfill('0') << std::hex - << npdu_test::instance_ids[service_idx] << ":" << std::setw(4) - << std::setfill('0') << std::hex - << npdu_test::method_ids[service_idx][method_idx]; - - if(call_service_sync_) - { - // We notify the sender thread every time a message was acknowledged - std::lock_guard lk(all_msg_acknowledged_mutexes_[service_idx][method_idx]); - all_msg_acknowledged_[service_idx][method_idx] = true; - all_msg_acknowledged_cvs_[service_idx][method_idx].notify_one(); - } - else - { - - std::lock_guard its_lock(number_of_acknowledged_messages_mutexes_[service_idx][method_idx]); - number_of_acknowledged_messages_[service_idx][method_idx]++; - - // We notify the sender thread only if all sent messages have been acknowledged - if(number_of_acknowledged_messages_[service_idx][method_idx] == number_of_messages_to_send_) - { - std::lock_guard lk(all_msg_acknowledged_mutexes_[service_idx][method_idx]); - // reset - number_of_acknowledged_messages_[service_idx][method_idx] = 0; - all_msg_acknowledged_[service_idx][method_idx] = true; - all_msg_acknowledged_cvs_[service_idx][method_idx].notify_one(); - } else if(number_of_acknowledged_messages_[service_idx][method_idx] % sliding_window_size == 0) - { - std::lock_guard lk(all_msg_acknowledged_mutexes_[service_idx][method_idx]); - all_msg_acknowledged_[service_idx][method_idx] = true; - all_msg_acknowledged_cvs_[service_idx][method_idx].notify_one(); - } - } -} - -template -void npdu_test_client::send() -{ - std::lock_guard its_lock(mutexes_[service_idx]); - blocked_[service_idx] = true; - conditions_[service_idx].notify_one(); -} - -template -void npdu_test_client::run() -{ - std::unique_lock its_lock(mutexes_[service_idx]); - while (!blocked_[service_idx]) - { - conditions_[service_idx].wait(its_lock); - } - current_payload_size_[service_idx] = 1; - - std::uint32_t max_allowed_payload = get_max_allowed_payload(); - - for (int var = 0; var < 4; ++var) { - payloads_[service_idx][var] = vsomeip::runtime::get()->create_payload(); - payload_data_[service_idx][var] = std::vector(); - } - - bool lastrun = false; - while (current_payload_size_[service_idx] <= max_allowed_payload) - { - // prepare the payloads w/ current payloadsize - for (int var = 0; var < 4; ++var) { - // assign 0x11 to first, 0x22 to second... - payload_data_[service_idx][var].assign( - current_payload_size_[service_idx], static_cast(0x11 * (var + 1))); - payloads_[service_idx][var]->set_data(payload_data_[service_idx][var]); - } - - // send the payloads to the service's methods - if(wait_for_replies_) { - call_service_sync_ ? send_messages_sync() : send_messages_async(); - } else { - send_messages_and_dont_wait_for_reply(); - } - - // Increase array size for next iteration - current_payload_size_[service_idx] *= 2; - - //special case to test the biggest payload possible as last test - // 16 Bytes are reserved for the SOME/IP header - if(current_payload_size_[service_idx] > max_allowed_payload - 16 && !lastrun) - { - current_payload_size_[service_idx] = max_allowed_payload - 16; - lastrun = true; - } - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - blocked_[service_idx] = false; - - { - std::lock_guard its_lock(finished_mutex_); - finished_[service_idx] = true; - } -} - - -std::uint32_t npdu_test_client::get_max_allowed_payload() -{ - std::uint32_t payload; - switch (max_payload_size) - { - case payloadsize::UDS: - payload = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE; - break; - case payloadsize::TCP: - payload = 4095; - break; - case payloadsize::UDP: - payload = VSOMEIP_MAX_UDP_MESSAGE_SIZE; - break; - default: - payload = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE; - break; - } - return payload; -} - -template -void npdu_test_client::send_messages_sync() -{ - std::thread t0 = start_send_thread_sync(); - std::thread t1 = start_send_thread_sync(); - std::thread t2 = start_send_thread_sync(); - std::thread t3 = start_send_thread_sync(); - t0.join(); - t1.join(); - t2.join(); - t3.join(); -} - -template -std::thread npdu_test_client::start_send_thread_sync() { - return std::thread([&]() { - all_msg_acknowledged_unique_locks_[service_idx][method_idx] = - std::unique_lock - (all_msg_acknowledged_mutexes_[service_idx][method_idx]); - - std::shared_ptr request = vsomeip::runtime::get()->create_request(use_tcp); - request->set_service(npdu_test::service_ids[service_idx]); - request->set_instance(npdu_test::instance_ids[service_idx]); - request->set_method(npdu_test::method_ids[service_idx][method_idx]); - request->set_payload(payloads_[service_idx][method_idx]); - for (std::uint32_t i = 0; i < number_of_messages_to_send_; i++) - { - all_msg_acknowledged_[service_idx][method_idx] = false; - app_->send(request); - - std::chrono::high_resolution_clock::time_point sent = - std::chrono::high_resolution_clock::now(); - - while(!all_msg_acknowledged_[service_idx][method_idx]) { - all_msg_acknowledged_cvs_[service_idx][method_idx].wait( - all_msg_acknowledged_unique_locks_[service_idx][method_idx]); - } - - std::chrono::nanoseconds waited_for_response = - std::chrono::high_resolution_clock::now() - sent; - if(waited_for_response < applicative_debounce_[service_idx][method_idx]) { - // make sure we don't send faster than debounce time + max retention time - std::this_thread::sleep_for( - applicative_debounce_[service_idx][method_idx] - - waited_for_response); - } - } - all_msg_acknowledged_unique_locks_[service_idx][method_idx].unlock(); - }); -} - -template -void npdu_test_client::send_messages_async() -{ - std::thread t0 = start_send_thread_async(); - std::thread t1 = start_send_thread_async(); - std::thread t2 = start_send_thread_async(); - std::thread t3 = start_send_thread_async(); - t0.join(); - t1.join(); - t2.join(); - t3.join(); -} - -template -std::thread npdu_test_client::start_send_thread_async() { - return std::thread([&]() { - all_msg_acknowledged_unique_locks_[service_idx][method_idx] = - std::unique_lock - (all_msg_acknowledged_mutexes_[service_idx][method_idx]); - std::shared_ptr request = vsomeip::runtime::get()->create_request(use_tcp); - request->set_service(npdu_test::service_ids[service_idx]); - request->set_instance(npdu_test::instance_ids[service_idx]); - request->set_method(npdu_test::method_ids[service_idx][method_idx]); - request->set_payload(payloads_[service_idx][method_idx]); - for (std::uint32_t i = 0; i < number_of_messages_to_send_; i++) - { - app_->send(request); - - if((i+1) == number_of_messages_to_send_ || (i+1) % sliding_window_size == 0) { - // wait until all send messages have been acknowledged - // as long we wait lk is released; after wait returns lk is reacquired - while(!all_msg_acknowledged_[service_idx][method_idx]) { - all_msg_acknowledged_cvs_[service_idx][method_idx].wait( - all_msg_acknowledged_unique_locks_[service_idx][method_idx]); - } - // Reset condition variable - all_msg_acknowledged_[service_idx][method_idx] = false; - } - // make sure we don't send faster than debounce time + max retention time - std::this_thread::sleep_for(applicative_debounce_[service_idx][method_idx]); - } - all_msg_acknowledged_unique_locks_[service_idx][method_idx].unlock(); - }); -} - -template -void npdu_test_client::send_messages_and_dont_wait_for_reply() -{ - std::thread t0 = start_send_thread(); - std::thread t1 = start_send_thread(); - std::thread t2 = start_send_thread(); - std::thread t3 = start_send_thread(); - t0.join(); - t1.join(); - t2.join(); - t3.join(); -} - -template -std::thread npdu_test_client::start_send_thread() { - return std::thread([&]() { - std::shared_ptr request = vsomeip::runtime::get()->create_request(use_tcp); - request->set_service(npdu_test::service_ids[service_idx]); - request->set_instance(npdu_test::instance_ids[service_idx]); - request->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); - request->set_method(npdu_test::method_ids[service_idx][method_idx]); - request->set_payload(payloads_[service_idx][method_idx]); - for (std::uint32_t i = 0; i < number_of_messages_to_send_; i++) - { - app_->send(request); - // make sure we don't send faster than debounce time + max retention time - std::this_thread::sleep_for(applicative_debounce_[service_idx][method_idx]); - } - }); -} - -void npdu_test_client::wait_for_all_senders() { - bool all_finished(false); - while (!all_finished) { - { - std::lock_guard its_lock(finished_mutex_); - if (std::all_of(finished_.begin(), finished_.end(), [](bool i) { return i; })) { - all_finished = true; - } - } - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - join_sender_thread(); - - if (!wait_for_replies_ || !call_service_sync_) { - // sleep longer here as sending is asynchronously and it's necessary - // to wait until all messages have left the application - VSOMEIP_INFO << "Sleeping for 180sec since the client is running " - "in --dont-wait-for-replies or --async mode. " - "Otherwise it might be possible that not all messages leave the " - "application."; - for(int i = 0; i < 180; i++) { - std::this_thread::sleep_for(std::chrono::seconds(1)); - std::cout << "."; - std::cout.flush(); - } - } else { - std::this_thread::sleep_for(std::chrono::seconds(5)); - } - stop(); -} - -TEST(someip_npdu_test, send_different_payloads) -{ - // get the configuration - std::shared_ptr its_configuration; - auto its_plugin = vsomeip::plugin_manager::get()->get_plugin( - vsomeip::plugin_type_e::CONFIGURATION_PLUGIN, VSOMEIP_CFG_LIBRARY); - if (its_plugin) { - auto its_config_plugin = std::dynamic_pointer_cast(its_plugin); - if (its_config_plugin) { - its_configuration = its_config_plugin->get_configuration(""); - } - } - if (!its_configuration) { - ADD_FAILURE() << "No configuration object. " - "Either memory overflow or loading error detected!"; - return; - } - - // used to store the debounce times - std::array, 4> applicative_debounce; - - // query the debouncetimes from the configuration. We want to know the - // debounce times which the _clients_ of this service have to comply with - // when they send requests to this service. - // This is necessary as we must ensure a applicative debouncing greater than - // debounce time + maximum retention time. Therefore the send threads sleep - // for this amount of time after sending a message. - for(int service_id = 0; service_id < 4; service_id++) { - for(int method_id = 0; method_id < 4; method_id++) { - std::chrono::nanoseconds debounce(0), retention(0); - its_configuration->get_configured_timing_requests( - npdu_test::service_ids[service_id], - its_configuration->get_unicast_address(npdu_test::service_ids[service_id], - npdu_test::instance_ids[service_id]), - its_configuration->get_unreliable_port( - npdu_test::service_ids[service_id], - npdu_test::instance_ids[service_id]), - npdu_test::method_ids[service_id][method_id], - &debounce, &retention); - if (debounce == std::chrono::nanoseconds(VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO) && - retention == std::chrono::nanoseconds(VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO)) { - // no timings specified don't don't sleep after sending... - applicative_debounce[service_id][method_id] = - std::chrono::milliseconds(0); - } else { - // we add 1 milliseconds to sleep a little bit longer - applicative_debounce[service_id][method_id] = std::chrono::duration_cast< - std::chrono::milliseconds>(debounce + retention) - + std::chrono::milliseconds(1); - - } - - } - } - - npdu_test_client test_client_(use_tcp, call_service_sync, - sliding_window_size, wait_for_replies, - applicative_debounce); - test_client_.init(); - test_client_.start(); -} - - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - std::string tcp_enable("--TCP"); - std::string udp_enable("--UDP"); - std::string sync_enable("--sync"); - std::string async_enable("--async"); - std::string no_reply_enable("--dont-wait-for-replies"); - std::string sliding_window_size_param("--sliding-window-size"); - std::string max_payload_size_param("--max-payload-size"); - std::string shutdown_service_disable_param("--dont-shutdown-service"); - std::string help("--help"); - - int i = 1; - while (i < argc) - { - if (tcp_enable == argv[i]) { - use_tcp = true; - } else if (udp_enable == argv[i]) { - use_tcp = false; - } else if (sync_enable == argv[i]) { - call_service_sync = true; - } else if (async_enable == argv[i]) { - call_service_sync = false; - } else if (no_reply_enable == argv[i]) { - wait_for_replies = false; - } else if (sliding_window_size_param == argv[i] && i + 1 < argc) { - i++; - std::stringstream converter(argv[i]); - converter >> sliding_window_size; - } else if (max_payload_size_param == argv[i] && i + 1 < argc) { - i++; - if (std::string("UDS") == argv[i]) { - max_payload_size = payloadsize::UDS; - } else if (std::string("TCP") == argv[i]) { - max_payload_size = payloadsize::TCP; - } else if (std::string("UDP") == argv[i]) { - max_payload_size = payloadsize::UDP; - } - } else if (shutdown_service_disable_param == argv[i]) { - shutdown_service_at_end = false; - } else if (help == argv[i]) { - VSOMEIP_INFO << "Parameters:\n" - << "--TCP: Send messages via TCP\n" - << "--UDP: Send messages via UDP (default)\n" - << "--sync: Wait for acknowledge before sending next message (default)\n" - << "--async: Send multiple messages w/o waiting for" - " acknowledge of service\n" - << "--dont-wait-for-replies: Just send out the messages w/o waiting for " - "a reply by the service (use REQUEST_NO_RETURN message type)\n" - << "--sliding-window-size: Number of messages to send before waiting " - "for acknowledge of service. Default: " << sliding_window_size << "\n" - << "--max-payload-size: limit the maximum payloadsize of send requests. One of {" - "UDS (=" << VSOMEIP_MAX_LOCAL_MESSAGE_SIZE << "byte), " - "UDP (=" << VSOMEIP_MAX_UDP_MESSAGE_SIZE << "byte), " - "TCP (=" << VSOMEIP_MAX_TCP_MESSAGE_SIZE << "byte)}, default: UDS\n" - << "--dont-shutdown-service: Don't shutdown the service upon " - "finishing of the payload test\n" - << "--help: print this help"; - } - i++; - } - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/npdu_tests/npdu_test_client.hpp b/test/npdu_tests/npdu_test_client.hpp deleted file mode 100644 index 980c16a..0000000 --- a/test/npdu_tests/npdu_test_client.hpp +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef PAYLOADTESTCLIENT_HPP_ -#define NPDUTESTCLIENT_HPP_ - -#include - -#include - -#include -#include -#include -#include -#include - -#include "../npdu_tests/npdu_test_globals.hpp" -#include "../someip_test_globals.hpp" - -class npdu_test_client -{ -public: - npdu_test_client(bool _use_tcp, bool _call_service_sync, - std::uint32_t _sliding_window_size, - bool _wait_for_replies, - std::array, 4> _applicative_debounce); - ~npdu_test_client(); - void init(); - void start(); - void stop(); - void join_sender_thread(); - void on_state(vsomeip::state_type_e _state); - template void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, - bool _is_available); - template void on_message( - const std::shared_ptr &_response); - template void send(); - template void run(); - -private: - template void send_messages_sync(); - template std::thread start_send_thread_sync(); - template void send_messages_async(); - template std::thread start_send_thread_async(); - template void send_messages_and_dont_wait_for_reply(); - std::uint32_t get_max_allowed_payload(); - template void register_availability_handler(); - template void register_message_handler_for_all_service_methods(); - template void register_message_handler(); - template - std::thread start_send_thread(); - void wait_for_all_senders(); - -private: - std::shared_ptr app_; - std::shared_ptr request_; - bool call_service_sync_; - bool wait_for_replies_; - std::uint32_t sliding_window_size_; - - std::array mutexes_; - std::array conditions_; - std::array blocked_; - std::array is_available_; - const std::uint32_t number_of_messages_to_send_; - std::uint32_t number_of_sent_messages_[npdu_test::service_ids.size()]; - std::array, - npdu_test::service_ids.size()> number_of_acknowledged_messages_; - std::array, - npdu_test::service_ids.size()> number_of_acknowledged_messages_mutexes_; - - std::array current_payload_size_; - - std::array, - npdu_test::service_ids.size()> all_msg_acknowledged_; - std::array, - npdu_test::service_ids.size()> all_msg_acknowledged_mutexes_; - std::array, npdu_test::method_ids[0].size()>, - npdu_test::service_ids.size()> all_msg_acknowledged_unique_locks_; - std::array< - std::array, - npdu_test::service_ids.size()> all_msg_acknowledged_cvs_; - std::array acknowledgements_; - std::array, 4> applicative_debounce_; - std::array< - std::array, - npdu_test::method_ids[0].size()>, - npdu_test::service_ids.size()> payloads_; - std::array< - std::array, - npdu_test::method_ids[0].size()>, - npdu_test::service_ids.size()> payload_data_; - std::array senders_; - std::mutex finished_mutex_; - std::array finished_; - std::thread finished_waiter_; -}; - -#endif /* NPDUTESTCLIENT_HPP_ */ diff --git a/test/npdu_tests/npdu_test_client_no_npdu_start.sh b/test/npdu_tests/npdu_test_client_no_npdu_start.sh deleted file mode 100755 index bc84421..0000000 --- a/test/npdu_tests/npdu_test_client_no_npdu_start.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the routing manager daemon and the -# clients with one command. This is necessary as ctest - which is used to run -# the tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the routing -# manager daemon and the clients and checks if all of them exit successfully. - -FAIL=0 - -if [ $# -lt 2 ]; then - echo "Error: Please pass a protocol and communication mode to this script." - echo "Valid protocols are [UDP,TCP]." - echo "Valid communication modes are [sync, async]." - echo "For example $> $0 UDP sync" - exit 1; -fi - -FAIL=0 -PROTOCOL=$1 -COMMUNICATION_MODE=$2 - -start_clients(){ - export VSOMEIP_CONFIGURATION=npdu_test_client_no_npdu.json - - # Start the routing manager daemon - export VSOMEIP_APPLICATION_NAME=npdu_test_routing_manager_daemon_client_side - ./npdu_test_rmd_client_side & - - # sleep 1 second to let the RMD startup. - sleep 1 - # Start client 1 - export VSOMEIP_APPLICATION_NAME=npdu_test_client_one - ./npdu_test_client_1 $* & - - # Start client 2 - export VSOMEIP_APPLICATION_NAME=npdu_test_client_two - ./npdu_test_client_2 $* & - - # Start client 3 - export VSOMEIP_APPLICATION_NAME=npdu_test_client_three - ./npdu_test_client_3 $* & - - # Start client 4 - export VSOMEIP_APPLICATION_NAME=npdu_test_client_four - ./npdu_test_client_4 $* & -} - -wait_for_bg_processes(){ - # Wait until client and service are finished - for job in $(jobs -p) - do - # Fail gets incremented if one of the jobs exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) - done - - # Check if everything exited successfully - if [ $FAIL -eq 0 ] - then - echo "All clients exited successfully" - else - echo "Something went wrong" - exit 1 - fi -} - -if [ $# -eq 0 ] -then - echo "Error: Please pass a mode to this script: UDP or TCP." - echo "For example $> $0 UDP" -fi - -echo "Contacting services via $PROTOCOL" -start_clients --$PROTOCOL --max-payload-size $PROTOCOL --$COMMUNICATION_MODE -wait_for_bg_processes - -exit 0 diff --git a/test/npdu_tests/npdu_test_client_npdu_start.sh b/test/npdu_tests/npdu_test_client_npdu_start.sh deleted file mode 100755 index 70b6c53..0000000 --- a/test/npdu_tests/npdu_test_client_npdu_start.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the routing manager daemon and the -# clients with one command. This is necessary as ctest - which is used to run -# the tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the routing -# manager daemon and the clients and checks if all of them exit successfully. - -if [ $# -lt 2 ]; then - echo "Error: Please pass a protocol and communication mode to this script." - echo "Valid protocols are [UDP,TCP]." - echo "Valid communication modes are [sync, async]." - echo "For example $> $0 UDP sync" - exit 1; -fi - -FAIL=0 -PROTOCOL=$1 -COMMUNICATION_MODE=$2 - -start_clients(){ - export VSOMEIP_CONFIGURATION=npdu_test_client_npdu.json - - # Start the routing manager daemon - export VSOMEIP_APPLICATION_NAME=npdu_test_routing_manager_daemon_client_side - ./npdu_test_rmd_client_side & - - # sleep 1 second to let the RMD startup. - sleep 1 - # Start client 1 - export VSOMEIP_APPLICATION_NAME=npdu_test_client_one - ./npdu_test_client_1 $* & - - # Start client 2 - export VSOMEIP_APPLICATION_NAME=npdu_test_client_two - ./npdu_test_client_2 $* & - - # Start client 3 - export VSOMEIP_APPLICATION_NAME=npdu_test_client_three - ./npdu_test_client_3 $* & - - # Start client 4 - export VSOMEIP_APPLICATION_NAME=npdu_test_client_four - ./npdu_test_client_4 $* & -} - -wait_for_bg_processes(){ - # Wait until client and service are finished - for job in $(jobs -p) - do - # Fail gets incremented if one of the jobs exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) - done - - # Check if everything exited successfully - if [ $FAIL -eq 0 ] - then - echo "All clients exited successfully" - else - echo "Something went wrong" - exit 1 - fi -} - - -echo "Contacting services via $PROTOCOL" -start_clients --$PROTOCOL --max-payload-size $PROTOCOL --$COMMUNICATION_MODE -wait_for_bg_processes - -exit 0 diff --git a/test/npdu_tests/npdu_test_globals.hpp b/test/npdu_tests/npdu_test_globals.hpp deleted file mode 100644 index 8cee3ee..0000000 --- a/test/npdu_tests/npdu_test_globals.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef NPDU_TESTS_NPDU_TEST_GLOBALS_HPP_ -#define NPDU_TESTS_NPDU_TEST_GLOBALS_HPP_ - -namespace npdu_test { - -// Routing manager daemon -constexpr vsomeip::client_t RMD_CLIENT_ID_CLIENT_SIDE = 0x6666; -constexpr vsomeip::service_t RMD_SERVICE_ID_CLIENT_SIDE = 0x6666; - -constexpr vsomeip::client_t RMD_CLIENT_ID_SERVICE_SIDE = 0x6667; -constexpr vsomeip::service_t RMD_SERVICE_ID_SERVICE_SIDE = 0x6667; - -constexpr vsomeip::instance_t RMD_INSTANCE_ID = 0x6666; -constexpr vsomeip::method_t RMD_SHUTDOWN_METHOD_ID = 0x6666; - - - -constexpr vsomeip::method_t NPDU_SERVICE_SHUTDOWNMETHOD_ID = 0x7777; - -constexpr std::array service_ids = - { 0x1000, 0x2000, 0x3000, 0x4000 }; -constexpr std::array instance_ids = - { service_ids[0] >> 12, - service_ids[1] >> 12, - service_ids[2] >> 12, - service_ids[3] >> 12 }; -constexpr std::array, 4> method_ids = {{ - { service_ids[0]+1, service_ids[0]+2 ,service_ids[0]+3 ,service_ids[0]+4 }, - { service_ids[1]+1, service_ids[1]+2 ,service_ids[1]+3 ,service_ids[1]+4 }, - { service_ids[2]+1, service_ids[2]+2 ,service_ids[2]+3 ,service_ids[2]+4 }, - { service_ids[3]+1, service_ids[3]+2 ,service_ids[3]+3 ,service_ids[3]+4 } -}}; - -constexpr std::array client_ids_clients = - { 0x1111, 0x2222, 0x3333, 0x4444 }; - -constexpr std::array client_ids_services = service_ids; - -} -#endif /* NPDU_TESTS_NPDU_TEST_GLOBALS_HPP_ */ diff --git a/test/npdu_tests/npdu_test_rmd.cpp b/test/npdu_tests/npdu_test_rmd.cpp deleted file mode 100644 index 1174a91..0000000 --- a/test/npdu_tests/npdu_test_rmd.cpp +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include - -#include "../npdu_tests/npdu_test_rmd.hpp" - -#include -#include "npdu_test_globals.hpp" - -#include "../npdu_tests/npdu_test_globals.hpp" - -npdu_test_rmd::npdu_test_rmd() : - app_(vsomeip::runtime::get()->create_application()), - is_registered_(false), - blocked_(false), - offer_thread_(std::bind(&npdu_test_rmd::run, this)) -{ - // TODO Auto-generated constructor stub -} - -void npdu_test_rmd::init() { - std::lock_guard its_lock(mutex_); - - app_->init(); - -#ifdef RMD_CLIENT_SIDE - app_->register_message_handler(npdu_test::RMD_SERVICE_ID_CLIENT_SIDE, -#elif defined (RMD_SERVICE_SIDE) - app_->register_message_handler(npdu_test::RMD_SERVICE_ID_SERVICE_SIDE, -#endif - npdu_test::RMD_INSTANCE_ID, npdu_test::RMD_SHUTDOWN_METHOD_ID, - std::bind(&npdu_test_rmd::on_message_shutdown, - this, std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&npdu_test_rmd::on_state, this, - std::placeholders::_1)); -} - -void npdu_test_rmd::start() { - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void npdu_test_rmd::stop() { - VSOMEIP_INFO << "Stopping..."; - - app_->unregister_message_handler(npdu_test::RMD_SERVICE_ID_CLIENT_SIDE, - npdu_test::RMD_INSTANCE_ID, npdu_test::RMD_SHUTDOWN_METHOD_ID); - app_->unregister_state_handler(); - offer_thread_.join(); - app_->stop(); -} - -void npdu_test_rmd::on_state( - vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : - "deregistered."); - - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - if(!is_registered_) - { - std::lock_guard its_lock(mutex_); - is_registered_ = true; - blocked_ = true; - // "start" the run method thread - condition_.notify_one(); - } - } - else - { - is_registered_ = false; - } -} - -void npdu_test_rmd::on_message_shutdown( - const std::shared_ptr& _request) { - (void)_request; - std::shared_ptr request = vsomeip::runtime::get()->create_request(false); -#ifdef RMD_CLIENT_SIDE - static int counter = 0; - counter++; - VSOMEIP_INFO << counter << " of " << npdu_test::client_ids_clients.size() - << " clients are finished."; - - if (counter == npdu_test::client_ids_clients.size()) { - VSOMEIP_INFO << "All clients are finished, notify routing manager daemon on service side."; - // notify the RMD_SERVICE_SIDE that he can shutdown as well - std::this_thread::sleep_for(std::chrono::seconds(1)); - request->set_service(npdu_test::RMD_SERVICE_ID_SERVICE_SIDE); - request->set_instance(npdu_test::RMD_INSTANCE_ID); - request->set_method(npdu_test::RMD_SHUTDOWN_METHOD_ID); - request->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); - app_->send(request); - std::this_thread::sleep_for(std::chrono::seconds(5)); - stop(); - } -#elif defined RMD_SERVICE_SIDE - VSOMEIP_INFO << "All clients are finished shutting down services"; - // shutdown all services - for(unsigned int i = 0; i < npdu_test::service_ids.size(); i++) { - request->set_service(npdu_test::service_ids[i]); - request->set_instance(npdu_test::instance_ids[i]); - request->set_method(npdu_test::NPDU_SERVICE_SHUTDOWNMETHOD_ID); - request->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); - app_->send(request); - } - app_->stop_offer_service(npdu_test::RMD_SERVICE_ID_SERVICE_SIDE, npdu_test::RMD_INSTANCE_ID); - - VSOMEIP_INFO << "Wait a few seconds until all services are shutdown."; - std::atomic finished(false); - for (int i = 0; !finished && i < 20; i++) { - app_->get_offered_services_async( - vsomeip::offer_type_e::OT_REMOTE, - [&](const std::vector> &_services){ - if (_services.empty()) { - finished = true; - } - }); - std::this_thread::sleep_for(std::chrono::seconds(1)); - } - stop(); -#endif -} - -void npdu_test_rmd::join_shutdown_thread() { - shutdown_thread_.join(); -} - -void npdu_test_rmd::run() { - std::unique_lock its_lock(mutex_); - while (!blocked_) - condition_.wait(its_lock); -#ifdef RMD_CLIENT_SIDE - app_->offer_service(npdu_test::RMD_SERVICE_ID_CLIENT_SIDE, npdu_test::RMD_INSTANCE_ID); -#elif defined (RMD_SERVICE_SIDE) - app_->offer_service(npdu_test::RMD_SERVICE_ID_SERVICE_SIDE, npdu_test::RMD_INSTANCE_ID); -#endif -} - -TEST(someip_npdu_test, offer_routing_manager_functionality) -{ - npdu_test_rmd daemon; - daemon.init(); - daemon.start(); -} - -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} - - diff --git a/test/npdu_tests/npdu_test_rmd.hpp b/test/npdu_tests/npdu_test_rmd.hpp deleted file mode 100644 index 0b1e28d..0000000 --- a/test/npdu_tests/npdu_test_rmd.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef NPDU_TESTS_NPDUTESTROUTINGMANAGERDAEMON_HPP_ -#define NPDU_TESTS_NPDUTESTROUTINGMANAGERDAEMON_HPP_ - -#include - -#include - -#include -#include -#include -#include - -class npdu_test_rmd { - -public: - npdu_test_rmd(); - void init(); - void start(); - void stop(); - void on_state(vsomeip::state_type_e _state); - void on_message_shutdown(const std::shared_ptr &_request); - void join_shutdown_thread(); - void run(); - -private: - std::shared_ptr app_; - bool is_registered_; - - std::mutex mutex_; - std::mutex mutex2_; - std::condition_variable condition_; - std::condition_variable condition2_; - bool blocked_; - bool blocked2_; - std::thread offer_thread_; - std::thread shutdown_thread_; - -}; - -#endif /* NPDU_TESTS_NPDUTESTROUTINGMANAGERDAEMON_HPP_ */ diff --git a/test/npdu_tests/npdu_test_service.cpp b/test/npdu_tests/npdu_test_service.cpp deleted file mode 100644 index ccbdd66..0000000 --- a/test/npdu_tests/npdu_test_service.cpp +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "../npdu_tests/npdu_test_service.hpp" -#include "../npdu_tests/npdu_test_globals.hpp" - -#include -#include "../../implementation/configuration/include/configuration.hpp" -#include "../../implementation/configuration/include/configuration_impl.hpp" -#include "../../implementation/configuration/include/configuration_plugin.hpp" -#include "../../implementation/plugin/include/plugin_manager_impl.hpp" - - - -// this variable is set during compile time to create 4 service binaries of -// which each of them offers a service. -// Based on this number the service id, instance id and method ids are -// selected from the arrays defined in npdu_test_globals.hpp -#ifndef SERVICE_NUMBER -#define SERVICE_NUMBER 0 -#endif - -npdu_test_service::npdu_test_service(vsomeip::service_t _service_id, - vsomeip::instance_t _instance_id, - std::array _method_ids, - std::array _debounce_times, - std::array _max_retention_times) : - app_(vsomeip::runtime::get()->create_application()), - is_registered_(false), - method_ids_(_method_ids), - debounce_times_(_debounce_times), - max_retention_times_(_max_retention_times), - service_id_(_service_id), - instance_id_(_instance_id), - blocked_(false), - allowed_to_shutdown_(false), - number_of_received_messages_(0), - offer_thread_(std::bind(&npdu_test_service::run, this)), - shutdown_thread_(std::bind(&npdu_test_service::stop, this)) -{ - // init timepoints of last received message to one hour before now. - // needed that the first message which arrives isn't registered as undershot - // debounce time - for(auto &tp : timepoint_last_received_message_) { - tp = std::chrono::steady_clock::now() - std::chrono::hours(1); - } -} - -void npdu_test_service::init() -{ - std::lock_guard its_lock(mutex_); - - app_->init(); - - register_message_handler<0>(); - register_message_handler<1>(); - register_message_handler<2>(); - register_message_handler<3>(); - - app_->register_message_handler(service_id_, instance_id_, - npdu_test::NPDU_SERVICE_SHUTDOWNMETHOD_ID, - std::bind(&npdu_test_service::on_message_shutdown, this, - std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&npdu_test_service::on_state, this, - std::placeholders::_1)); -} - -template -void npdu_test_service::register_message_handler() { - app_->register_message_handler(service_id_, instance_id_, method_ids_[method_idx], - std::bind(&npdu_test_service::on_message, this, - std::placeholders::_1)); -} - -void npdu_test_service::start() -{ - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void npdu_test_service::stop() -{ - std::unique_lock its_lock(shutdown_mutex_); - while (!allowed_to_shutdown_) { - shutdown_condition_.wait(its_lock); - } - - VSOMEIP_INFO << "Stopping..."; - if (!undershot_debounce_times_.empty()) { - std::chrono::microseconds sum(0); - for (const auto& t : undershot_debounce_times_) { - sum += t; - } - double average = static_cast(sum.count())/static_cast(undershot_debounce_times_.size()); - VSOMEIP_INFO << "[" - << std::setw(4) << std::setfill('0') << std::hex << service_id_ << "." - << std::setw(4) << std::setfill('0') << std::hex << instance_id_ << "]: " - << " Debounce time was undershot " << std::dec << undershot_debounce_times_.size() << "/" << number_of_received_messages_ - << "(" << std::setprecision(2) << (static_cast(undershot_debounce_times_.size()) / static_cast(number_of_received_messages_)) * 100.00 - << "%) on average: " << std::setprecision(4) << average << "µs"; - } - app_->unregister_message_handler(service_id_, instance_id_, method_ids_[0]); - app_->unregister_message_handler(service_id_, instance_id_, method_ids_[1]); - app_->unregister_message_handler(service_id_, instance_id_, method_ids_[2]); - app_->unregister_message_handler(service_id_, instance_id_, method_ids_[3]); - app_->unregister_message_handler(service_id_, - instance_id_, npdu_test::NPDU_SERVICE_SHUTDOWNMETHOD_ID); - app_->unregister_state_handler(); - offer_thread_.join(); - stop_offer(); - app_->stop(); -} - -void npdu_test_service::offer() -{ - app_->offer_service(service_id_, instance_id_); -} - -void npdu_test_service::stop_offer() -{ - app_->stop_offer_service(service_id_, instance_id_); -} - -void npdu_test_service::join_shutdown_thread() { - shutdown_thread_.join(); -} - -void npdu_test_service::on_state(vsomeip::state_type_e _state) -{ - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : - "deregistered."); - - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - if(!is_registered_) - { - std::lock_guard its_lock(mutex_); - is_registered_ = true; - blocked_ = true; - // "start" the run method thread - condition_.notify_one(); - } - } - else - { - is_registered_ = false; - } -} - -template -void npdu_test_service::check_times() { - std::lock_guard its_lock(timepoint_mutexes_[method_idx]); - // what time is it? - std::chrono::steady_clock::time_point now = - std::chrono::steady_clock::now(); - // how long is it since we received the last message? - std::chrono::nanoseconds time_since_last_message = - std::chrono::duration_cast( - now - timepoint_last_received_message_[method_idx]); - // store the current time - timepoint_last_received_message_[method_idx] = now; - - // check if the debounce time was undershot - if (time_since_last_message < debounce_times_[method_idx]) { - const auto time_undershot = std::chrono::duration_cast< - std::chrono::microseconds>(debounce_times_[method_idx] - time_since_last_message); - undershot_debounce_times_.push_back(time_undershot); - } - // check if maximum retention time was exceeded - // Disabled as it can't be guaranteed that exact every max retention time a - // message leaves the client endpoint. -#if 0 - if(time_since_last_message > max_retention_times_[method_idx]) { - VSOMEIP_ERROR << std::setw(4) << std::setfill('0') << std::hex - << service_id_ << ":" << std::setw(4) << std::setfill('0') - << std::hex << instance_id_ << ":" << std::setw(4) << std::setfill('0') - << std::hex << npdu_test::method_ids[SERVICE_NUMBER][method_idx] - << ": max_retention_time exceeded by: " << std::dec - << std::chrono::duration_cast( - time_since_last_message - max_retention_times_[method_idx]).count() - << "ms"; - GTEST_FATAL_FAILURE_("Max retention time was exceeded"); - } -#endif -} - -template -void npdu_test_service::on_message(const std::shared_ptr& _request) -{ - number_of_received_messages_++; - check_times(); - VSOMEIP_DEBUG << __func__ << " 0x" << std::setw(4) << std::setfill('0') << std::hex - << method_ids_[method_idx] << " payload size: " - << std::dec << _request->get_payload()->get_length(); - if(_request->get_message_type() != vsomeip::message_type_e::MT_REQUEST_NO_RETURN) { - std::shared_ptr its_response = - vsomeip::runtime::get()->create_response(_request); - app_->send(its_response); - } -} - -void npdu_test_service::on_message_shutdown( - const std::shared_ptr& _request) -{ - (void)_request; - VSOMEIP_DEBUG << "Number of received messages: " << number_of_received_messages_; - VSOMEIP_INFO << "Shutdown method was called, going down now."; - - std::lock_guard its_lock(shutdown_mutex_); - allowed_to_shutdown_ = true; - shutdown_condition_.notify_one(); -} - -void npdu_test_service::run() -{ - std::unique_lock its_lock(mutex_); - while (!blocked_) - condition_.wait(its_lock); - - offer(); -} - -TEST(someip_npdu_test, offer_service_and_check_debounce_times) -{ - // get the configuration - std::shared_ptr its_configuration; - auto its_plugin = vsomeip::plugin_manager::get()->get_plugin( - vsomeip::plugin_type_e::CONFIGURATION_PLUGIN, VSOMEIP_CFG_LIBRARY); - if (its_plugin) { - auto its_config_plugin = std::dynamic_pointer_cast(its_plugin); - if (its_config_plugin) { - its_configuration = its_config_plugin->get_configuration(""); - } - } - if (!its_configuration) { - ADD_FAILURE() << "No configuration object. " - "Either memory overflow or loading error detected!"; - return; - } - - // used to store the debounce times - std::array debounce_times; - std::array max_retention_times; - - - // query the debouncetimes from the configuration. We want to know the - // debounce times which the _clients_ of this service have to comply with - // when they send requests to this service. This is necessary as we want to - // check on the service side if they adhere to them. - // client one will only query method one, client two will only query method - // two and so on. - for(int i = 0; i < 4; i++) { - std::chrono::nanoseconds debounce(0), retention(0); - its_configuration->get_configured_timing_requests( - npdu_test::service_ids[SERVICE_NUMBER], - its_configuration->get_unicast_address().to_string(), - its_configuration->get_unreliable_port( - npdu_test::service_ids[SERVICE_NUMBER], - npdu_test::instance_ids[SERVICE_NUMBER]), - npdu_test::method_ids[SERVICE_NUMBER][i], - &debounce_times[i], - &max_retention_times[i]); - if (debounce == std::chrono::nanoseconds(VSOMEIP_DEFAULT_NPDU_DEBOUNCING_NANO) && - retention == std::chrono::nanoseconds(VSOMEIP_DEFAULT_NPDU_MAXIMUM_RETENTION_NANO)) { - // no timings specified - checks in check_times() should never - // report an error in this case. - // set debounce time to 0 this can't be undershot - debounce_times[i] = std::chrono::nanoseconds(0); - // set max retention time its max, this won't be exceeded - max_retention_times[i] = std::chrono::nanoseconds::max(); - } - } - - npdu_test_service test_service( - npdu_test::service_ids[SERVICE_NUMBER], - npdu_test::instance_ids[SERVICE_NUMBER], - npdu_test::method_ids[SERVICE_NUMBER], - debounce_times, max_retention_times); - test_service.init(); - test_service.start(); - test_service.join_shutdown_thread(); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - int i = 1; - while (i < argc) - { - if(std::string("--help") == argv[i]) - { - VSOMEIP_INFO << "Parameters:\n" - << "--help: print this help"; - } - i++; - } - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/npdu_tests/npdu_test_service.hpp b/test/npdu_tests/npdu_test_service.hpp deleted file mode 100644 index bef0680..0000000 --- a/test/npdu_tests/npdu_test_service.hpp +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef NPDUTESTSERVICE_HPP_ -#define NPDUTESTSERVICE_HPP_ -#include - -#include - -#include -#include -#include -#include -#include -#include - -class npdu_test_service -{ -public: - npdu_test_service(vsomeip::service_t _service_id, - vsomeip::instance_t _instance_id, - std::array _method_ids, - std::array _debounce_times, - std::array _max_retention_times); - void init(); - void start(); - void stop(); - void offer(); - void stop_offer(); - void join_shutdown_thread(); - void on_state(vsomeip::state_type_e _state); - template void on_message(const std::shared_ptr &_request); - void on_message_shutdown(const std::shared_ptr &_request); - void run(); - -private: - template void check_times(); - template void register_message_handler(); - -private: - std::shared_ptr app_; - bool is_registered_; - std::array method_ids_; - std::array debounce_times_; - std::array max_retention_times_; - std::array timepoint_last_received_message_; - std::array timepoint_mutexes_; - std::deque undershot_debounce_times_; - vsomeip::service_t service_id_; - vsomeip::instance_t instance_id_; - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - std::mutex shutdown_mutex_; - std::condition_variable shutdown_condition_; - bool allowed_to_shutdown_; - std::uint32_t number_of_received_messages_; - std::thread offer_thread_; - std::thread shutdown_thread_; -}; - -#endif /* NPDUTESTSERVICE_HPP_ */ diff --git a/test/npdu_tests/npdu_test_service_no_npdu_start.sh b/test/npdu_tests/npdu_test_service_no_npdu_start.sh deleted file mode 100755 index cf05aaa..0000000 --- a/test/npdu_tests/npdu_test_service_no_npdu_start.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the routing manager daemon and the -# services with one command. This is necessary as ctest - which is used to run -# the tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the routing -# manager daemon and the services and checks if all of them exit successfully. - -FAIL=0 - -start_services(){ - export VSOMEIP_CONFIGURATION=npdu_test_service_no_npdu.json - - # Start the routing manager daemon - export VSOMEIP_APPLICATION_NAME=npdu_test_routing_manager_daemon_service_side - ./npdu_test_rmd_service_side & - - # sleep 1 second to let the RMD startup. - sleep 1 - - # Start service 1 - export VSOMEIP_APPLICATION_NAME=npdu_test_service_one - ./npdu_test_service_1 $* & - - # Start service 2 - export VSOMEIP_APPLICATION_NAME=npdu_test_service_two - ./npdu_test_service_2 $* & - - # Start service 3 - export VSOMEIP_APPLICATION_NAME=npdu_test_service_three - ./npdu_test_service_3 $* & - - # Start service 4 - export VSOMEIP_APPLICATION_NAME=npdu_test_service_four - ./npdu_test_service_4 $* & -} - -wait_for_bg_processes(){ - # Wait until client and service are finished - for job in $(jobs -p) - do - # Fail gets incremented if one of the jobs exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) - done - - # Check if everything exited successfully - if [ $FAIL -eq 0 ] - then - echo "All services exited successfully" - else - echo "Something went wrong" - exit 1 - fi -} - -start_services -wait_for_bg_processes - -exit 0 diff --git a/test/npdu_tests/npdu_test_service_npdu_start.sh b/test/npdu_tests/npdu_test_service_npdu_start.sh deleted file mode 100755 index 0ca238b..0000000 --- a/test/npdu_tests/npdu_test_service_npdu_start.sh +++ /dev/null @@ -1,64 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the routing manager daemon and the -# services with one command. This is necessary as ctest - which is used to run -# the tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the routing -# manager daemon and the services and checks if all of them exit successfully. - -FAIL=0 - -start_services(){ - export VSOMEIP_CONFIGURATION=npdu_test_service_npdu.json - - # Start the routing manager daemon - export VSOMEIP_APPLICATION_NAME=npdu_test_routing_manager_daemon_service_side - ./npdu_test_rmd_service_side & - - # sleep 1 second to let the RMD startup. - sleep 1 - - # Start service 1 - export VSOMEIP_APPLICATION_NAME=npdu_test_service_one - ./npdu_test_service_1 $* & - - # Start service 2 - export VSOMEIP_APPLICATION_NAME=npdu_test_service_two - ./npdu_test_service_2 $* & - - # Start service 3 - export VSOMEIP_APPLICATION_NAME=npdu_test_service_three - ./npdu_test_service_3 $* & - - # Start service 4 - export VSOMEIP_APPLICATION_NAME=npdu_test_service_four - ./npdu_test_service_4 $* & -} - -wait_for_bg_processes(){ - # Wait until client and service are finished - for job in $(jobs -p) - do - # Fail gets incremented if one of the jobs exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) - done - - # Check if everything exited successfully - if [ $FAIL -eq 0 ] - then - echo "All services exited successfully" - else - echo "Something went wrong" - exit 1 - fi -} - -start_services -wait_for_bg_processes - -exit 0 diff --git a/test/npdu_tests/npdu_test_starter.sh b/test/npdu_tests/npdu_test_starter.sh deleted file mode 100755 index c405adc..0000000 --- a/test/npdu_tests/npdu_test_starter.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the routing manager daemon and the -# services with one command. This is necessary as ctest - which is used to run -# the tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the routing -# manager daemon and the services and checks if all of them exit successfully. - -FAIL=0 - -if [ $# -lt 2 ]; then - echo "Error: Please pass a protocol and communication mode to this script." - echo "Valid protocols are [UDP,TCP]." - echo "Valid communication modes are [sync, async]." - echo "For example $> $0 UDP sync" - exit 1; -fi - -start_services(){ - export VSOMEIP_CONFIGURATION=npdu_test_service_npdu.json - - # Start the routing manager daemon - export VSOMEIP_APPLICATION_NAME=npdu_test_routing_manager_daemon_service_side - ./npdu_test_rmd_service_side & - - # sleep 1 second to let the RMD startup. - sleep 1 - - # Start service 1 - export VSOMEIP_APPLICATION_NAME=npdu_test_service_one - ./npdu_test_service_1 $* & - - # Start service 2 - export VSOMEIP_APPLICATION_NAME=npdu_test_service_two - ./npdu_test_service_2 $* & - - # Start service 3 - export VSOMEIP_APPLICATION_NAME=npdu_test_service_three - ./npdu_test_service_3 $* & - - # Start service 4 - export VSOMEIP_APPLICATION_NAME=npdu_test_service_four - ./npdu_test_service_4 $* & -} - -wait_for_bg_processes(){ - # Wait until client and service are finished - for job in $(jobs -p) - do - # Fail gets incremented if one of the jobs exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) - done - - # Check if everything exited successfully - if [ $FAIL -eq 0 ] - then - echo "All services exited successfully" - else - echo "Something went wrong" - exit 1 - fi -} - - -start_services - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting magic cookies test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./npdu_test_client_npdu_start.sh $*\"" & -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./npdu_test_client_npdu_start.sh $*" & -elif [ ! -z "$JENKINS" ]; then - echo "starting npdu_test on slave Docker" - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./npdu_test_client_npdu_start.sh $*\" >> $WS_ROOT/slave_test_output 2>&1" & - -else -sleep 1 -cat <> $WS_ROOT/slave_test_output 2>&1" & -else -cat < should be rejected as there is already a service instance -# running in the network - -# Array for client pids -CLIENT_PIDS=() -export VSOMEIP_CONFIGURATION=offer_test_external_master.json -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! -# Start the services -./offer_test_service 2 & -PID_SERVICE_TWO=$! -echo "SERVICE_TWO pid $PID_SERVICE_TWO" - -./offer_test_client SUBSCRIBE & -CLIENT_PIDS+=($!) -echo "client pid ${CLIENT_PIDS[0]}" - -# Wait until all clients are finished -for job in ${CLIENT_PIDS[*]} -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting offer test on slave LXC offer_test_external_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./offer_test_external_slave_starter.sh\"" & -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS; ./offer_test_external_slave_starter.sh" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test ; ./offer_test_external_slave_starter.sh\" >> $WS_ROOT/slave_test_output 2>&1" & -else -cat <> $WS_ROOT/slave_test_output 2>&1" & -else -cat < -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "offer_test_globals.hpp" - -class offer_test_big_sd_msg_client { -public: - offer_test_big_sd_msg_client(struct offer_test::service_info _service_info) : - service_info_(_service_info), - app_(vsomeip::runtime::get()->create_application("offer_test_big_sd_msg_client")), - wait_until_registered_(true), - wait_until_service_available_(true), - wait_until_subscribed_(true), - wait_for_stop_(true), - stop_thread_(std::bind(&offer_test_big_sd_msg_client::wait_for_stop, this)), - send_thread_(std::bind(&offer_test_big_sd_msg_client::send, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&offer_test_big_sd_msg_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, - std::bind(&offer_test_big_sd_msg_client::on_message, this, - std::placeholders::_1)); - - // register availability for all other services and request their event. - app_->register_availability_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, - std::bind(&offer_test_big_sd_msg_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3), 0x1, 0x1); - std::set its_eventgroups; - its_eventgroups.insert(offer_test::big_msg_eventgroup_id); - for (std::uint16_t s = 1; s <= offer_test::big_msg_number_services; s++) { - app_->request_service(s,0x1,0x1,0x1); - app_->request_event(s,0x1, offer_test::big_msg_event_id, - its_eventgroups, vsomeip::event_type_e::ET_EVENT, - vsomeip::reliability_type_e::RT_UNKNOWN); - app_->subscribe(s, 0x1,offer_test::big_msg_eventgroup_id, 0x1, - offer_test::big_msg_event_id); - services_available_subribed_[s] = std::make_pair(false,0); - app_->register_subscription_status_handler(s,0x1, - offer_test::big_msg_eventgroup_id, - offer_test::big_msg_event_id, - std::bind(&offer_test_big_sd_msg_client::subscription_status_changed, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)); - } - app_->start(); - } - - ~offer_test_big_sd_msg_client() { - send_thread_.join(); - stop_thread_.join(); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_WARNING << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - VSOMEIP_DEBUG << "Service [" << std::setw(4) - << std::setfill('0') << std::hex << _service << "." << _instance - << "] is " << (_is_available ? "available":"not available") << "."; - - std::lock_guard its_lock(mutex_); - if(_is_available) { - auto found_service = services_available_subribed_.find(_service); - if (found_service != services_available_subribed_.end()) { - found_service->second.first = true; - if (std::all_of(services_available_subribed_.cbegin(), - services_available_subribed_.cend(), - [](const services_available_subribed_t::value_type& v) { - return v.second.first; - } - )) { - VSOMEIP_WARNING << "************************************************************"; - VSOMEIP_WARNING << "All services available!"; - VSOMEIP_WARNING << "************************************************************"; - wait_until_service_available_ = false; - condition_.notify_one(); - } - } - } - } - - void subscription_status_changed(const vsomeip::service_t _service, - const vsomeip::instance_t _instance, - const vsomeip::eventgroup_t _eventgroup, - const vsomeip::event_t _event, - const uint16_t _error) { - EXPECT_EQ(0x1, _instance); - EXPECT_EQ(offer_test::big_msg_eventgroup_id, _eventgroup); - EXPECT_EQ(offer_test::big_msg_event_id, _event); - VSOMEIP_DEBUG << "Service [" << std::setw(4) - << std::setfill('0') << std::hex << _service << "." << _instance - << "] has " << (!_error ? "sent subscribe ack":" sent subscribe_nack") << "."; - if (_error == 0x0 /*OK*/) { - - std::lock_guard its_lock(mutex_); - auto found_service = services_available_subribed_.find(_service); - if (found_service != services_available_subribed_.end()) { - found_service->second.second++; - if (found_service->second.second > 1) { - ADD_FAILURE() << "Registered subscription status handler was " - "called " << std::dec << found_service->second.second - << " times for service: " << std::hex - << found_service->first; - } - if (std::all_of(services_available_subribed_.cbegin(), - services_available_subribed_.cend(), - [](const services_available_subribed_t::value_type& v) { - return v.second.second == 1; - } - )) { - VSOMEIP_WARNING << "************************************************************"; - VSOMEIP_WARNING << "All subscription were acknowledged!"; - VSOMEIP_WARNING << "************************************************************"; - wait_until_subscribed_ = false; - condition_.notify_one(); - } - } - } - }; - - void on_message(const std::shared_ptr &_message) { - if (_message->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - on_response(_message); - } - } - - void on_response(const std::shared_ptr &_message) { - EXPECT_EQ(0x1, _message->get_service()); - EXPECT_EQ(service_info_.shutdown_method_id, _message->get_method()); - EXPECT_EQ(0x1, _message->get_instance()); - if(service_info_.shutdown_method_id == _message->get_method()) { - std::lock_guard its_lock(stop_mutex_); - wait_for_stop_ = false; - VSOMEIP_INFO << "going down"; - stop_condition_.notify_one(); - } - } - - void send() { - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - while (wait_until_service_available_) { - condition_.wait(its_lock); - } - - while (wait_until_subscribed_) { - condition_.wait(its_lock); - } - - std::this_thread::sleep_for(std::chrono::seconds(5)); - std::shared_ptr its_req = vsomeip::runtime::get()->create_request(); - its_req->set_service(1); - its_req->set_instance(1); - its_req->set_interface_version(0x1); - its_req->set_method(service_info_.shutdown_method_id); - app_->send(its_req); - } - - void wait_for_stop() { - std::unique_lock its_lock(stop_mutex_); - while (wait_for_stop_) { - stop_condition_.wait(its_lock); - } - VSOMEIP_INFO << "going down"; - app_->clear_all_handler(); - app_->stop(); - } - -private: - struct offer_test::service_info service_info_; - std::shared_ptr app_; - - bool wait_until_registered_; - bool wait_until_service_available_; - bool wait_until_subscribed_; - std::mutex mutex_; - std::condition_variable condition_; - - bool wait_for_stop_; - std::mutex stop_mutex_; - std::condition_variable stop_condition_; - - typedef std::map> services_available_subribed_t; - services_available_subribed_t services_available_subribed_; - std::thread stop_thread_; - std::thread send_thread_; -}; - -TEST(someip_offer_test_big_sd_msg, subscribe_or_call_method_at_service) -{ - offer_test_big_sd_msg_client its_sample(offer_test::service); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/offer_tests/offer_test_big_sd_msg_service.cpp b/test/offer_tests/offer_test_big_sd_msg_service.cpp deleted file mode 100644 index 5424be3..0000000 --- a/test/offer_tests/offer_test_big_sd_msg_service.cpp +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "offer_test_globals.hpp" - -class offer_test_big_sd_msg_service { -public: - offer_test_big_sd_msg_service(struct offer_test::service_info _service_info) : - service_info_(_service_info), - // service with number 1 uses "routingmanagerd" as application name - // this way the same json file can be reused for all local tests - // including the ones with routingmanagerd - app_(vsomeip::runtime::get()->create_application("offer_test_big_sd_msg_service")), - wait_until_registered_(true), - wait_until_client_subscribed_to_all_services_(true), - shutdown_method_called_(false), - offer_thread_(std::bind(&offer_test_big_sd_msg_service::run, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&offer_test_big_sd_msg_service::on_state, this, - std::placeholders::_1)); - - // offer field - std::set its_eventgroups; - its_eventgroups.insert(offer_test::big_msg_eventgroup_id); - for (std::uint16_t s = 1; s <= offer_test::big_msg_number_services; s++) { - app_->offer_event(s, 0x1, - offer_test::big_msg_event_id, its_eventgroups, - vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); - app_->register_subscription_handler(s, 0x1, offer_test::big_msg_eventgroup_id, - std::bind(&offer_test_big_sd_msg_service::on_subscription, - this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4, s)); - subscriptions_[s] = 0; - } - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, service_info_.shutdown_method_id, - std::bind(&offer_test_big_sd_msg_service::on_shutdown_method_called, this, - std::placeholders::_1)); - - - app_->start(); - } - - ~offer_test_big_sd_msg_service() { - offer_thread_.join(); - } - - void offer() { - for (std::uint16_t s = 1; s <= offer_test::big_msg_number_services; s++) { - app_->offer_service(s,0x1,0x1,0x1); - } - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - bool on_subscription(vsomeip::client_t _client, - std::uint32_t _uid, std::uint32_t _gid, - bool _subscribed, - vsomeip::service_t _service) { - (void)_client; - (void)_uid; - (void)_gid; - if (_subscribed) { - subscriptions_[_service]++; - EXPECT_EQ(1u, subscriptions_[_service]); - if (std::all_of(subscriptions_.begin(), subscriptions_.end(), [&](const subscriptions_t::value_type& v){ - return v.second == 1; - })) { - std::lock_guard its_lock(mutex_); - wait_until_client_subscribed_to_all_services_ = false; - VSOMEIP_WARNING << "************************************************************"; - VSOMEIP_WARNING << "Client subscribed to all services!"; - VSOMEIP_WARNING << "************************************************************"; - condition_.notify_one(); - } - } - - return true; - } - - void on_shutdown_method_called(const std::shared_ptr &_message) { - app_->send(vsomeip::runtime::get()->create_response(_message)); - std::this_thread::sleep_for(std::chrono::seconds(1)); - VSOMEIP_WARNING << "************************************************************"; - VSOMEIP_WARNING << "Shutdown method called -> going down!"; - VSOMEIP_WARNING << "************************************************************"; - shutdown_method_called_ = true; - for (std::uint16_t s = 1; s <= offer_test::big_msg_number_services; s++) { - app_->stop_offer_service(s,0x1,0x1,0x1); - } - app_->clear_all_handler(); - app_->stop(); - } - - void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - - while (wait_until_client_subscribed_to_all_services_) { - condition_.wait(its_lock); - } - } - -private: - struct offer_test::service_info service_info_; - std::shared_ptr app_; - - bool wait_until_registered_; - bool wait_until_client_subscribed_to_all_services_; - std::mutex mutex_; - std::condition_variable condition_; - std::atomic shutdown_method_called_; - typedef std::map subscriptions_t; - subscriptions_t subscriptions_; - std::thread offer_thread_; -}; - -TEST(someip_offer_test_big_sd_msg, notify_increasing_counter) -{ - offer_test_big_sd_msg_service its_sample(offer_test::service); -} - - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/offer_tests/offer_test_big_sd_msg_slave_starter.sh b/test/offer_tests/offer_test_big_sd_msg_slave_starter.sh deleted file mode 100755 index 32379ed..0000000 --- a/test/offer_tests/offer_test_big_sd_msg_slave_starter.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -FAIL=0 -# Rejecting offer for which there is already a remote offer: -# * start daemon -# * start application which offers service -# * start daemon remotely -# * start same application which offers the same service again remotely -# -> should be rejected as there is already a service instance -# running in the network - -export VSOMEIP_CONFIGURATION=offer_test_big_sd_msg_slave.json -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! -sleep 1 -# Start the services -./offer_test_big_sd_msg_service & -PID_SERVICE_TWO=$! -sleep 1 - -# Wait until all clients and services are finished -for job in $PID_SERVICE_TWO -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill $PID_VSOMEIPD -sleep 1 - - - -# Check if everything went well -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/offer_tests/offer_test_client.cpp b/test/offer_tests/offer_test_client.cpp deleted file mode 100644 index 4a7e5eb..0000000 --- a/test/offer_tests/offer_test_client.cpp +++ /dev/null @@ -1,288 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#ifdef ANDROID -#include "../../configuration/include/internal_android.hpp" -#else -#include "../../configuration/include/internal.hpp" -#endif // ANDROID - -#include "offer_test_globals.hpp" - -enum operation_mode_e { - SUBSCRIBE, - METHODCALL -}; - -class offer_test_client { -public: - offer_test_client(struct offer_test::service_info _service_info, operation_mode_e _mode) : - service_info_(_service_info), - operation_mode_(_mode), - app_(vsomeip::runtime::get()->create_application("offer_test_client")), - wait_until_registered_(true), - wait_until_service_available_(true), - wait_for_stop_(true), - last_received_counter_(0), - last_received_response_(std::chrono::steady_clock::now()), - number_received_responses_(0), - stop_thread_(std::bind(&offer_test_client::wait_for_stop, this)), - send_thread_(std::bind(&offer_test_client::send, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&offer_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, - std::bind(&offer_test_client::on_message, this, - std::placeholders::_1)); - - // register availability for all other services and request their event. - app_->register_availability_handler(service_info_.service_id, - service_info_.instance_id, - std::bind(&offer_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - app_->request_service(service_info_.service_id, - service_info_.instance_id); - - if (operation_mode_ == operation_mode_e::SUBSCRIBE) { - std::set its_eventgroups; - its_eventgroups.insert(service_info_.eventgroup_id); - app_->request_event(service_info_.service_id, - service_info_.instance_id, service_info_.event_id, - its_eventgroups, vsomeip::event_type_e::ET_EVENT, - vsomeip::reliability_type_e::RT_BOTH); - - app_->subscribe(service_info_.service_id, service_info_.instance_id, - service_info_.eventgroup_id, vsomeip::DEFAULT_MAJOR); - } - - app_->start(); - } - - ~offer_test_client() { - send_thread_.join(); - stop_thread_.join(); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - VSOMEIP_INFO << "Service [" << std::setw(4) - << std::setfill('0') << std::hex << _service << "." << _instance - << "] is " << (_is_available ? "available":"not available") << "."; - std::lock_guard its_lock(mutex_); - if(_is_available) { - wait_until_service_available_ = false; - condition_.notify_one(); - } else { - wait_until_service_available_ = true; - condition_.notify_one(); - } - } - - void on_message(const std::shared_ptr &_message) { - if(_message->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - on_notification(_message); - } else if (_message->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - on_response(_message); - } - } - - void on_notification(const std::shared_ptr &_message) { - std::shared_ptr its_payload(_message->get_payload()); - EXPECT_EQ(4u, its_payload->get_length()); - vsomeip::byte_t *d = its_payload->get_data(); - static std::uint32_t number_received_notifications(0); - std::uint32_t counter(0); - counter |= static_cast(d[0] << 24); - counter |= static_cast(d[0] << 16); - counter = counter | static_cast((d[2] << 8)); - counter = counter | static_cast(d[3]); - - VSOMEIP_DEBUG - << "Received a notification with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_session() << "] from Service/Method [" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_service() << "/" << std::setw(4) << std::setfill('0') - << std::hex << _message->get_method() <<"] got:" << std::dec << counter; - - ASSERT_GT(counter, last_received_counter_); - last_received_counter_ = counter; - ++number_received_notifications; - - if(number_received_notifications >= 250) { - std::lock_guard its_lock(stop_mutex_); - wait_for_stop_ = false; - VSOMEIP_INFO << "going down"; - stop_condition_.notify_one(); - } - } - - void on_response(const std::shared_ptr &_message) { - ++number_received_responses_; - static bool first(true); - if (first) { - first = false; - last_received_response_ = std::chrono::steady_clock::now(); - return; - } - EXPECT_EQ(service_info_.service_id, _message->get_service()); - EXPECT_EQ(service_info_.method_id, _message->get_method()); - EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - ASSERT_LT(std::chrono::duration_cast( - std::chrono::steady_clock::now() - last_received_response_).count(), - (std::chrono::milliseconds(VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT) - + std::chrono::milliseconds(1000)).count()); - last_received_response_ = std::chrono::steady_clock::now(); - std::cout << "."; - std::cout.flush(); - } - - void send() { - if (operation_mode_ != operation_mode_e::METHODCALL) { - return; - } - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - while (wait_until_service_available_) { - condition_.wait(its_lock); - } - its_lock.unlock(); - its_lock.release(); - - for (int var = 0; var < offer_test::number_of_messages_to_send; ++var) { - bool send(false); - { - std::lock_guard its_lock(mutex_); - send = !wait_until_service_available_; - } - if (send) { - std::shared_ptr its_req = vsomeip::runtime::get()->create_request(); - its_req->set_service(service_info_.service_id); - its_req->set_instance(service_info_.instance_id); - its_req->set_method(service_info_.method_id); - app_->send(its_req); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } else { - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } - } - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - { - std::lock_guard its_lock(stop_mutex_); - wait_for_stop_ = false; - VSOMEIP_INFO << "going down. Sent " << offer_test::number_of_messages_to_send - << " requests and received " << number_received_responses_ - << " responses"; - stop_condition_.notify_one(); - } - } - - void wait_for_stop() { - std::unique_lock its_lock(stop_mutex_); - while (wait_for_stop_) { - stop_condition_.wait(its_lock); - } - VSOMEIP_INFO << "going down"; - app_->clear_all_handler(); - app_->stop(); - } - -private: - struct offer_test::service_info service_info_; - operation_mode_e operation_mode_; - std::shared_ptr app_; - - bool wait_until_registered_; - bool wait_until_service_available_; - std::mutex mutex_; - std::condition_variable condition_; - - bool wait_for_stop_; - std::mutex stop_mutex_; - std::condition_variable stop_condition_; - - std::uint32_t last_received_counter_; - std::chrono::steady_clock::time_point last_received_response_; - std::atomic number_received_responses_; - std::thread stop_thread_; - std::thread send_thread_; -}; - -static operation_mode_e passed_mode = operation_mode_e::SUBSCRIBE; - -TEST(someip_offer_test, subscribe_or_call_method_at_service) -{ - offer_test_client its_sample(offer_test::service, passed_mode); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if(argc < 2) { - std::cerr << "Please specify a operation mode, like: " << argv[0] << " SUBSCRIBE" << std::endl; - std::cerr << "Valid operation modes are SUBSCRIBE and METHODCALL" << std::endl; - return 1; - } - - if (std::string("SUBSCRIBE") == std::string(argv[1])) { - passed_mode = operation_mode_e::SUBSCRIBE; - } else if (std::string("METHODCALL") == std::string(argv[1])) { - passed_mode = operation_mode_e::METHODCALL; - } else { - std::cerr << "Wrong operation mode passed, exiting" << std::endl; - std::cerr << "Please specify a operation mode, like: " << argv[0] << " SUBSCRIBE" << std::endl; - std::cerr << "Valid operation modes are SUBSCRIBE and METHODCALL" << std::endl; - return 1; - } - -#if 0 - if (argc >= 4 && std::string("SAME_SERVICE_ID") == std::string(argv[3])) { - use_same_service_id = true; - } else { - use_same_service_id = false; - } -#endif - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/offer_tests/offer_test_external_sd_msg_sender.cpp b/test/offer_tests/offer_test_external_sd_msg_sender.cpp deleted file mode 100644 index cc75b8d..0000000 --- a/test/offer_tests/offer_test_external_sd_msg_sender.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include - -#include - -#include - -static char* passed_address; - -TEST(someip_offer_test, send_offer_service_sd_message) -{ - try { - boost::asio::io_service io; - boost::system::error_code ec; - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(passed_address)), - 30490); - - boost::asio::ip::udp::socket udp_socket(io); - - boost::asio::ip::udp::endpoint rx_endpoint_(boost::asio::ip::udp::v4(), 30490); - udp_socket.open(rx_endpoint_.protocol(), ec); - - if(ec) - std::cout <<" udp_socket open create error "< should be rejected as there is already a service instance -# running in the network - -export VSOMEIP_CONFIGURATION=offer_test_external_slave.json -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -echo "calling availabiliy checker" - -./offer_test_service_availability_checker & - -PID_AVAILABILITY_CHECKER=$! - -echo "waiting for offer_test_service_availability_checker" - -# wait until the services on the remote node were started as well -wait $PID_AVAILABILITY_CHECKER - -# kill the routing manager services -kill $PID_VSOMEIPD - -./offer_test_external_sd_msg_sender $1 & - - - diff --git a/test/offer_tests/offer_test_external_slave_starter.sh b/test/offer_tests/offer_test_external_slave_starter.sh deleted file mode 100755 index 5c30e87..0000000 --- a/test/offer_tests/offer_test_external_slave_starter.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -FAIL=0 -# Rejecting offer for which there is already a remote offer: -# * start daemon -# * start application which offers service -# * start daemon remotely -# * start same application which offers the same service again remotely -# -> should be rejected as there is already a service instance -# running in the network - -export VSOMEIP_CONFIGURATION=offer_test_external_slave.json -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! -sleep 1 -# Start the services -./offer_test_service_external 2 & -PID_SERVICE_TWO=$! -sleep 1 - -# Wait until all clients and services are finished -for job in $PID_SERVICE_TWO -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill $PID_VSOMEIPD -sleep 1 - - - -# Check if everything went well -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/offer_tests/offer_test_globals.hpp b/test/offer_tests/offer_test_globals.hpp deleted file mode 100644 index ba69886..0000000 --- a/test/offer_tests/offer_test_globals.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef OFFER_TEST_GLOBALS_HPP_ -#define OFFER_TEST_GLOBALS_HPP_ - -namespace offer_test { - -struct service_info { - vsomeip::service_t service_id; - vsomeip::instance_t instance_id; - vsomeip::method_t method_id; - vsomeip::event_t event_id; - vsomeip::eventgroup_t eventgroup_id; - vsomeip::method_t shutdown_method_id; -}; - -struct service_info service = { 0x1111, 0x1, 0x1111, 0x1111, 0x1000, 0x1404 }; - -static constexpr int number_of_messages_to_send = 150; - -static constexpr std::uint16_t big_msg_number_services = 300; -static constexpr vsomeip::event_t big_msg_event_id = 0x8000; -static constexpr vsomeip::eventgroup_t big_msg_eventgroup_id = 0x1; -} - -#endif /* OFFER_TEST_GLOBALS_HPP_ */ diff --git a/test/offer_tests/offer_test_local.json b/test/offer_tests/offer_test_local.json deleted file mode 100644 index be8aa09..0000000 --- a/test/offer_tests/offer_test_local.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "unicast":"127.0.0.1", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "routing":"routingmanagerd", - "service-discovery": - { - "enable":"false" - } -} - diff --git a/test/offer_tests/offer_test_local_starter.sh b/test/offer_tests/offer_test_local_starter.sh deleted file mode 100755 index 6e5af18..0000000 --- a/test/offer_tests/offer_test_local_starter.sh +++ /dev/null @@ -1,298 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -FAIL=0 - -cat < should be -# rejected and an error message should be printed. -# * Message exchange with client application should not be interrupted. - -# Array for client pids -CLIENT_PIDS=() -export VSOMEIP_CONFIGURATION=offer_test_local.json -# Start the services -./offer_test_service 1 & -PID_SERVICE_ONE=$! -./offer_test_client SUBSCRIBE & -CLIENT_PIDS+=($!) -./offer_test_client SUBSCRIBE & -CLIENT_PIDS+=($!) - -./offer_test_service 2 & -PID_SERVICE_TWO=$! - -# Wait until all clients are finished -for job in ${CLIENT_PIDS[*]} -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill $PID_SERVICE_TWO -kill $PID_SERVICE_ONE -sleep 1 - - -cat < should be -# rejected and an error message should be printed. -# * Message exchange with client application should not be interrupted. - -# Array for client pids -CLIENT_PIDS=() -export VSOMEIP_CONFIGURATION=offer_test_local.json -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -# Start the services -./offer_test_service 2 & -PID_SERVICE_TWO=$! -./offer_test_client SUBSCRIBE & -CLIENT_PIDS+=($!) -./offer_test_client SUBSCRIBE & -CLIENT_PIDS+=($!) - -./offer_test_service 3 & -PID_SERVICE_THREE=$! - -# Wait until all clients are finished -for job in ${CLIENT_PIDS[*]} -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill $PID_SERVICE_THREE -kill $PID_SERVICE_TWO -sleep 1 -kill $PID_VSOMEIPD -sleep 1 - - -cat < should be -# accepted. -# * start another client which exchanges messages with the service -# * Client should now communicate with new offerer. - -# Array for client pids -CLIENT_PIDS=() -export VSOMEIP_CONFIGURATION=offer_test_local.json -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! -# Start the service -./offer_test_service 2 & -PID_SERVICE_TWO=$! - -# Start a client -./offer_test_client METHODCALL & -CLIENT_PIDS+=($!) - -# Kill the service -sleep 1 -kill -KILL $PID_SERVICE_TWO - -# reoffer the service -./offer_test_service 3 & -PID_SERVICE_THREE=$! - -# Start another client -./offer_test_client METHODCALL & -CLIENT_PIDS+=($!) - -# Wait until all clients are finished -for job in ${CLIENT_PIDS[*]} -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill $PID_SERVICE_THREE -kill $PID_VSOMEIPD -sleep 1 - -cat < should be -# marked as PENDING_OFFER and a ping should be sent to the paused -# application. -# * After the timeout passed the new offer should be accepted. -# * start client which exchanges messages with the service -# * Client should now communicate with new offerer. - -# Array for client pids -CLIENT_PIDS=() -export VSOMEIP_CONFIGURATION=offer_test_local.json -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! -# Start the service -./offer_test_service 2 & -PID_SERVICE_TWO=$! - -# Start a client -./offer_test_client METHODCALL & -CLIENT_PIDS+=($!) - -# Pause the service -sleep 1 -kill -STOP $PID_SERVICE_TWO - -# reoffer the service -./offer_test_service 3 & -PID_SERVICE_THREE=$! - -# Start another client -./offer_test_client METHODCALL & -CLIENT_PIDS+=($!) - -# Wait until all clients are finished -for job in ${CLIENT_PIDS[*]} -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill -CONT $PID_SERVICE_TWO -kill $PID_SERVICE_TWO -kill $PID_SERVICE_THREE -kill $PID_VSOMEIPD -sleep 1 - -cat < should be -# marked as PENDING_OFFER and a ping should be sent to the paused -# application. -# * start application which offers the same service again -> should be -# rejected as there is already a PENDING_OFFER pending. -# * After the timeout passed the new offer should be accepted. -# * start client which exchanges messages with the service -# * Client should now communicate with new offerer. - -# Array for client pids -CLIENT_PIDS=() -export VSOMEIP_CONFIGURATION=offer_test_local.json -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! -# Start the service -./offer_test_service 2 & -PID_SERVICE_TWO=$! - -# Start a client -./offer_test_client METHODCALL & -CLIENT_PIDS+=($!) - -# Pause the service -sleep 1 -kill -STOP $PID_SERVICE_TWO - -# reoffer the service -./offer_test_service 3 & -PID_SERVICE_THREE=$! - -# reoffer the service again to provoke rejecting as there is -# already a pending offer -./offer_test_service 4 & -PID_SERVICE_FOUR=$! - -# Start another client -./offer_test_client METHODCALL & -CLIENT_PIDS+=($!) - -# Wait until all clients are finished -for job in ${CLIENT_PIDS[*]} -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill -CONT $PID_SERVICE_TWO -kill $PID_SERVICE_TWO -kill $PID_SERVICE_THREE -kill $PID_SERVICE_FOUR -kill $PID_VSOMEIPD - - -# Check if everything went well -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/offer_tests/offer_test_service.cpp b/test/offer_tests/offer_test_service.cpp deleted file mode 100644 index 87bd7e0..0000000 --- a/test/offer_tests/offer_test_service.cpp +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "offer_test_globals.hpp" - -static std::string service_number; - -class offer_test_service { -public: - offer_test_service(struct offer_test::service_info _service_info) : - service_info_(_service_info), - // service with number 1 uses "routingmanagerd" as application name - // this way the same json file can be reused for all local tests - // including the ones with routingmanagerd - app_(vsomeip::runtime::get()->create_application( - (service_number == "1") ? "routingmanagerd" : - "offer_test_service" + service_number)), - counter_(0), - wait_until_registered_(true), - shutdown_method_called_(false), - offer_thread_(std::bind(&offer_test_service::run, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&offer_test_service::on_state, this, - std::placeholders::_1)); - - // offer field - std::set its_eventgroups; - its_eventgroups.insert(service_info_.eventgroup_id); - app_->offer_event(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_eventgroups, - vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_BOTH); - - inc_counter_and_notify(); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.method_id, - std::bind(&offer_test_service::on_request, this, - std::placeholders::_1)); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.shutdown_method_id, - std::bind(&offer_test_service::on_shutdown_method_called, this, - std::placeholders::_1)); - app_->start(); - } - - ~offer_test_service() { - offer_thread_.join(); - } - - void offer() { - app_->offer_service(service_info_.service_id, service_info_.instance_id); - // this is allowed - app_->offer_service(service_info_.service_id, service_info_.instance_id); - // this is not allowed and will be rejected - app_->offer_service(service_info_.service_id, service_info_.instance_id, 33, 4711); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_request(const std::shared_ptr &_message) { - app_->send(vsomeip::runtime::get()->create_response(_message)); - } - - void on_shutdown_method_called(const std::shared_ptr &_message) { - (void)_message; - shutdown_method_called_ = true; - // this is will trigger a warning - app_->stop_offer_service(service_info_.service_id, service_info_.instance_id, 44, 4711); - app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); - app_->clear_all_handler(); - app_->stop(); - } - - void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Notifying"; - while(!shutdown_method_called_) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - inc_counter_and_notify(); - } - } - - void inc_counter_and_notify() { - ++counter_; - // set value to field - const std::shared_ptr its_payload(vsomeip::runtime::get()->create_payload()); - std::vector its_data; - its_data.push_back(static_cast((counter_ & 0xFF000000) >> 24)); - its_data.push_back(static_cast((counter_ & 0xFF0000) >> 16)); - its_data.push_back(static_cast((counter_ & 0xFF00) >> 8)); - its_data.push_back(static_cast((counter_ & 0xFF))); - its_payload->set_data(its_data); - app_->notify(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_payload); - } - -private: - struct offer_test::service_info service_info_; - std::shared_ptr app_; - std::uint32_t counter_; - - bool wait_until_registered_; - std::mutex mutex_; - std::condition_variable condition_; - std::atomic shutdown_method_called_; - std::thread offer_thread_; -}; - -TEST(someip_offer_test, notify_increasing_counter) -{ - offer_test_service its_sample(offer_test::service); -} - - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if(argc < 2) { - std::cerr << "Please specify a service number, like: " << argv[0] << " 2" << std::endl; - return 1; - } - - service_number = std::string(argv[1]); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/offer_tests/offer_test_service_availability_checker.cpp b/test/offer_tests/offer_test_service_availability_checker.cpp deleted file mode 100644 index 3cef64f..0000000 --- a/test/offer_tests/offer_test_service_availability_checker.cpp +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "offer_test_globals.hpp" - - -class offer_test_service_availability_checker { -public: - offer_test_service_availability_checker(struct offer_test::service_info _service_info) : - service_info_(_service_info), - app_(vsomeip::runtime::get()->create_application()), - wait_until_registered_(true), - wait_for_stop_(true), - stop_thread_(std::bind(&offer_test_service_availability_checker::wait_for_stop, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&offer_test_service_availability_checker::on_state, this, - std::placeholders::_1)); - - // register availability for all other services and request their event. - app_->register_availability_handler(service_info_.service_id, - service_info_.instance_id, - std::bind(&offer_test_service_availability_checker::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - app_->request_service(service_info_.service_id, - service_info_.instance_id); - - app_->start(); - } - - ~offer_test_service_availability_checker() { - stop_thread_.join(); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "MY Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - VSOMEIP_INFO << "MY Service [" << std::setw(4) - << std::setfill('0') << std::hex << _service << "." << _instance - << "] is " << (_is_available ? "available":"not available") << "."; - std::lock_guard its_lock(mutex_); - if(_is_available) { - wait_for_stop_ = false; - stop_condition_.notify_one(); - } - } - - void wait_for_stop() { - VSOMEIP_INFO << " MY offer_test_service_availability_check wait_for_stop() "; - std::unique_lock its_lock(stop_mutex_); - while (wait_for_stop_) { - stop_condition_.wait(its_lock); - } - //VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex - // << client_number_ << "] all services are available. Going down"; - VSOMEIP_INFO << " MY offer_test_service_availability_check is going down "; - app_->clear_all_handler(); - app_->stop(); - } - -private: - struct offer_test::service_info service_info_; - std::shared_ptr app_; - - bool wait_until_registered_; - std::mutex mutex_; - std::condition_variable condition_; - - bool wait_for_stop_; - std::mutex stop_mutex_; - std::condition_variable stop_condition_; - std::thread stop_thread_; -}; - -TEST(someip_offer_test_external, wait_for_availability_and_exit) -{ - offer_test_service_availability_checker its_sample( - offer_test::service); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/offer_tests/offer_test_service_external.cpp b/test/offer_tests/offer_test_service_external.cpp deleted file mode 100644 index 5948f74..0000000 --- a/test/offer_tests/offer_test_service_external.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "offer_test_globals.hpp" - -static std::string service_number; - -class offer_test_service { -public: - offer_test_service(struct offer_test::service_info _service_info) : - service_info_(_service_info), - // service with number 1 uses "routingmanagerd" as application name - // this way the same json file can be reused for all local tests - // including the ones with routingmanagerd - app_(vsomeip::runtime::get()->create_application( - (service_number == "1") ? "routingmanagerd" : - "offer_test_service" + service_number)), - wait_until_registered_(true), - wait_until_service_available_(true), - offer_thread_(std::bind(&offer_test_service::run, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&offer_test_service::on_state, this, - std::placeholders::_1)); - - app_->register_availability_handler(service_info_.service_id, - service_info_.instance_id, - std::bind(&offer_test_service::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - app_->request_service(service_info_.service_id, - service_info_.instance_id); - app_->start(); - } - - ~offer_test_service() { - offer_thread_.join(); - } - - void offer() { - app_->offer_service(service_info_.service_id, service_info_.instance_id); - // this is allowed - app_->offer_service(service_info_.service_id, service_info_.instance_id); - // this is not allowed and will be rejected - app_->offer_service(service_info_.service_id, service_info_.instance_id, 33, 4711); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - VSOMEIP_INFO << "Service [" << std::setw(4) - << std::setfill('0') << std::hex << _service << "." << _instance - << "] is " << (_is_available ? "available":"not available") << "."; - std::lock_guard its_lock(mutex_); - if(_is_available) { - wait_until_service_available_ = false; - condition_.notify_one(); - } else { - wait_until_service_available_ = true; - condition_.notify_one(); - } - } - - void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; - { - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - - while(wait_until_service_available_) { - condition_.wait(its_lock); - } - } - - std::this_thread::sleep_for(std::chrono::seconds(1)); - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Calling stop method"; - std::shared_ptr msg(vsomeip::runtime::get()->create_request()); - msg->set_service(service_info_.service_id); - msg->set_instance(service_info_.instance_id); - msg->set_method(service_info_.shutdown_method_id); - msg->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); - app_->send(msg); - std::this_thread::sleep_for(std::chrono::seconds(2)); - app_->clear_all_handler(); - app_->stop(); - } - -private: - struct offer_test::service_info service_info_; - std::shared_ptr app_; - - bool wait_until_registered_; - bool wait_until_service_available_; - std::mutex mutex_; - std::condition_variable condition_; - std::thread offer_thread_; -}; - -TEST(someip_offer_test, notify_increasing_counter) -{ - offer_test_service its_sample(offer_test::service); -} - - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if(argc < 2) { - std::cerr << "Please specify a service number, like: " << argv[0] << " 2" << std::endl; - return 1; - } - - service_number = std::string(argv[1]); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/offered_services_info_test/offered_services_info_test_client.cpp b/test/offered_services_info_test/offered_services_info_test_client.cpp deleted file mode 100644 index 202d0a6..0000000 --- a/test/offered_services_info_test/offered_services_info_test_client.cpp +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#ifdef ANDROID -#include "../../configuration/include/internal_android.hpp" -#else -#include "../../configuration/include/internal.hpp" -#endif - -#include "offered_services_info_test_globals.hpp" - -enum operation_mode_e { - SUBSCRIBE, - METHODCALL -}; - -std::map> all_offered_services; -std::map> local_offered_services; -std::map> remote_offered_services; - -class offered_services_info_test_client { -public: - offered_services_info_test_client(struct offer_test::service_info _service_info,offer_test::service_info _remote_service_info, operation_mode_e _mode) : - service_info_(_service_info), - remote_service_info_(_remote_service_info), - operation_mode_(_mode), - app_(vsomeip::runtime::get()->create_application("offered_services_info_test_client")), - wait_until_registered_(true), - wait_until_service_available_(true), - wait_for_stop_(true), - last_received_response_(std::chrono::steady_clock::now()), - number_received_responses_(0), - stop_thread_(std::bind(&offered_services_info_test_client::wait_for_stop, this)), - test_offered_services_thread_(std::bind(&offered_services_info_test_client::test_offered_services, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - - local_offered_services[service_info_.service_id].insert(service_info_.instance_id); - all_offered_services[service_info_.service_id].insert(service_info_.instance_id); - - local_offered_services[service_info_.service_id].insert((vsomeip::instance_t)(service_info_.instance_id + 1)); - all_offered_services[service_info_.service_id].insert((vsomeip::instance_t)(service_info_.instance_id + 1)); - - // offer remote service ID 0x2222 instance ID 0x2 (port configuration added to json file) - remote_offered_services[remote_service_info_.service_id].insert(remote_service_info_.instance_id); - all_offered_services[remote_service_info_.service_id].insert(remote_service_info_.instance_id); - - remote_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 1)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 1)); - all_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 1)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 1)); - - remote_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 2)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 2)); - all_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 2)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 2)); - - app_->register_state_handler( - std::bind(&offered_services_info_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, - std::bind(&offered_services_info_test_client::on_message, this, - std::placeholders::_1)); - - app_->register_availability_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, - std::bind(&offered_services_info_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - // request all services - app_->request_service(service_info_.service_id, service_info_.instance_id); - app_->request_service(service_info_.service_id, vsomeip::instance_t(service_info_.instance_id + 1)); - app_->request_service(remote_service_info_.service_id, remote_service_info_.instance_id); - app_->request_service(vsomeip::service_t(remote_service_info_.service_id + 1), vsomeip::instance_t(remote_service_info_.instance_id + 1)); - app_->request_service(vsomeip::service_t(remote_service_info_.service_id + 2), vsomeip::instance_t(remote_service_info_.instance_id + 2)); - - app_->start(); - } - - ~offered_services_info_test_client() { - test_offered_services_thread_.join(); - stop_thread_.join(); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - VSOMEIP_INFO << "Service [" << std::setw(4) - << std::setfill('0') << std::hex << _service << "." << _instance - << "] is " << (_is_available ? "available":"not available") << "."; - static int services_available =0; - std::lock_guard its_lock(mutex_); - if(_is_available) { - services_available++; - if (services_available == 5) { - wait_until_service_available_ = false; - condition_.notify_one(); - } - } else { - wait_until_service_available_ = true; - condition_.notify_one(); - } - } - - void on_message(const std::shared_ptr &_message) { - if (_message->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - on_response(_message); - } - } - - void on_response(const std::shared_ptr &_message) { - ++number_received_responses_; - static bool first(true); - if (first) { - first = false; - last_received_response_ = std::chrono::steady_clock::now(); - return; - } - EXPECT_EQ(service_info_.service_id, _message->get_service()); - EXPECT_EQ(service_info_.method_id, _message->get_method()); - EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - ASSERT_LT(std::chrono::duration_cast( - std::chrono::steady_clock::now() - last_received_response_).count(), - (std::chrono::milliseconds(VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT) - + std::chrono::milliseconds(1000)).count()); - last_received_response_ = std::chrono::steady_clock::now(); - std::cout << "."; - std::cout.flush(); - } - - void test_offered_services() { - if (operation_mode_ != operation_mode_e::METHODCALL) { - return; - } - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - while (wait_until_service_available_) { - condition_.wait(its_lock); - } - its_lock.unlock(); - its_lock.release(); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - VSOMEIP_INFO << "TEST LOCAL SERVICES"; - app_->get_offered_services_async(vsomeip::offer_type_e::OT_LOCAL, std::bind(&offered_services_info_test_client::on_offered_services_local, this, std::placeholders::_1)); - - // send shutdown command to service - if (std::future_status::timeout == all_callbacks_received_.get_future().wait_for(std::chrono::seconds(15))) { - ADD_FAILURE() << "Didn't receive all callbacks within time"; - } else { - std::shared_ptr its_req = vsomeip::runtime::get()->create_request(); - its_req->set_service(service_info_.service_id); - its_req->set_instance(service_info_.instance_id); - its_req->set_method(service_info_.shutdown_method_id); - app_->send(its_req); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - { - std::lock_guard its_lock(stop_mutex_); - wait_for_stop_ = false; - VSOMEIP_INFO << "going down. Sent shutdown command to service"; - stop_condition_.notify_one(); - } - } - - void on_offered_services_local( const std::vector> &_services) { - std::cout << "ON OFFERED SERVICES LOCAL CALLBACK START" << std::endl; - EXPECT_EQ(2u, _services.size()); - bool local_service_test_failed(true); - for (auto its_pair : _services) { - local_service_test_failed = true; - std::cout << "CALLBACK VALUE -> Service: "<< std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; - auto found_service = local_offered_services.find(its_pair.first); - if (found_service != local_offered_services.end()) { - auto found_instance = found_service->second.find(its_pair.second); - if (found_instance != found_service->second.end()) { - local_service_test_failed = false; - } - } - EXPECT_FALSE(local_service_test_failed); - } - std::cout << "ON OFFERED SERVICES LOCAL CALLBACK END" << std::endl; - VSOMEIP_INFO << "TEST REMOTE SERVICES"; - app_->get_offered_services_async(vsomeip::offer_type_e::OT_REMOTE, std::bind(&offered_services_info_test_client::on_offered_services_remote, this, std::placeholders::_1)); - } - - void on_offered_services_remote( const std::vector> &_services) { - std::cout << "ON OFFERED SERVICES REMOTE CALLBACK START" << std::endl; - EXPECT_EQ(3u, _services.size()); - bool remote_service_test_failed(true); - for (auto its_pair : _services) { - remote_service_test_failed = true; - std::cout << "CALLBACK VALUE -> Service: " << std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; - auto found_service = remote_offered_services.find(its_pair.first); - if (found_service != remote_offered_services.end()) { - auto found_instance = found_service->second.find(its_pair.second); - if (found_instance != found_service->second.end()) { - remote_service_test_failed = false; - } - } - EXPECT_FALSE(remote_service_test_failed); - } - std::cout << "ON OFFERED SERVICES REMOTE CALLBACK END" << std::endl; - VSOMEIP_INFO << "TEST ALL SERVICES"; - app_->get_offered_services_async(vsomeip::offer_type_e::OT_ALL, std::bind(&offered_services_info_test_client::on_offered_services_all, this, std::placeholders::_1)); - } - - void on_offered_services_all( const std::vector> &_services) { - std::cout << "ON OFFERED SERVICES ALL CALLBACK START" << std::endl; - EXPECT_EQ(5u, _services.size()); - bool all_service_test_failed(true); - for (auto its_pair : _services) { - all_service_test_failed = true; - std::cout << "CALLBACK VALUE -> Service: " << std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; - auto found_service = all_offered_services.find(its_pair.first); - if (found_service != all_offered_services.end()) { - auto found_instance = found_service->second.find(its_pair.second); - if (found_instance != found_service->second.end()) { - all_service_test_failed = false; - } - } - EXPECT_FALSE(all_service_test_failed); - } - std::cout << "ON OFFERED SERVICES ALL CALLBACK END" << std::endl; - all_callbacks_received_.set_value(); - } - - void wait_for_stop() { - std::unique_lock its_lock(stop_mutex_); - while (wait_for_stop_) { - stop_condition_.wait(its_lock); - } - VSOMEIP_INFO << "going down"; - app_->clear_all_handler(); - app_->stop(); - } - -private: - struct offer_test::service_info service_info_; - struct offer_test::service_info remote_service_info_; - operation_mode_e operation_mode_; - std::shared_ptr app_; - - bool wait_until_registered_; - bool wait_until_service_available_; - std::mutex mutex_; - std::condition_variable condition_; - - bool wait_for_stop_; - std::mutex stop_mutex_; - std::condition_variable stop_condition_; - - std::chrono::steady_clock::time_point last_received_response_; - std::atomic number_received_responses_; - std::promise all_callbacks_received_; - std::thread stop_thread_; - std::thread test_offered_services_thread_; -}; - -static operation_mode_e passed_mode = operation_mode_e::METHODCALL; - -TEST(someip_offered_services_info_test, check_offered_services) -{ - offered_services_info_test_client its_sample(offer_test::service, offer_test::remote_service, passed_mode); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if(argc < 2) { - std::cerr << "Please specify a operation mode, like: " << argv[0] << " SUBSCRIBE" << std::endl; - std::cerr << "Valid operation modes are SUBSCRIBE and METHODCALL" << std::endl; - return 1; - } - - if (std::string("SUBSCRIBE") == std::string(argv[1])) { - passed_mode = operation_mode_e::SUBSCRIBE; - } else if (std::string("METHODCALL") == std::string(argv[1])) { - passed_mode = operation_mode_e::METHODCALL; - } else { - std::cerr << "Wrong operation mode passed, exiting" << std::endl; - std::cerr << "Please specify a operation mode, like: " << argv[0] << " SUBSCRIBE" << std::endl; - std::cerr << "Valid operation modes are SUBSCRIBE and METHODCALL" << std::endl; - return 1; - } - -#if 0 - if (argc >= 4 && std::string("SAME_SERVICE_ID") == std::string(argv[3])) { - use_same_service_id = true; - } else { - use_same_service_id = false; - } -#endif - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/offered_services_info_test/offered_services_info_test_globals.hpp b/test/offered_services_info_test/offered_services_info_test_globals.hpp deleted file mode 100644 index b74dfab..0000000 --- a/test/offered_services_info_test/offered_services_info_test_globals.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef OFFER_TEST_GLOBALS_HPP_ -#define OFFER_TEST_GLOBALS_HPP_ - -namespace offer_test { - -struct service_info { - vsomeip::service_t service_id; - vsomeip::instance_t instance_id; - vsomeip::method_t method_id; - vsomeip::event_t event_id; - vsomeip::eventgroup_t eventgroup_id; - vsomeip::method_t shutdown_method_id; -}; - -uint8_t num_all_offered_services = 5; -uint8_t num_local_offered_services = 2; -uint8_t num_remote_offered_services = 3; - - -struct service_info service = { 0x1111, 0x1, 0x1111, 0x1111, 0x1000, 0x1404 }; -struct service_info remote_service = { 0x2222, 0x2, 0x2222, 0x2222, 0x2000, 0x2808 }; -} - -#endif /* OFFER_TEST_GLOBALS_HPP_ */ diff --git a/test/offered_services_info_test/offered_services_info_test_local.json b/test/offered_services_info_test/offered_services_info_test_local.json deleted file mode 100644 index 872ebd2..0000000 --- a/test/offered_services_info_test/offered_services_info_test_local.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "unicast" : "127.0.0.1", - "diagnosis":"0x12", - "logging" : - { - "level" : "warning", - "console" : "true", - "file" : - { - "enable" : "false", - "path" : "/tmp/vsomeip.log" - }, - - "dlt" : "false" - }, - - "applications" : - [ - { - "name" : "offered_services_info_test_service", - "id" : "0x1277" - } - ], - - "services" : - [ - { - "service" : "0x1111", - "instance" : "0x1" - }, - { - "service" : "0x2222", - "instance" : "0x2", - "reliable" : { "port" : "30502" }, - "unreliable" : "31002" - }, - { - "service" : "0x2223", - "instance" : "0x3", - "reliable" : { "port" : "30503" } - }, - { - "service" : "0x2224", - "instance" : "0x4", - "unreliable" : "31004" - } - ], - - "routing" : "routingmanagerd", - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp" - } -} diff --git a/test/offered_services_info_test/offered_services_info_test_local_starter.sh b/test/offered_services_info_test/offered_services_info_test_local_starter.sh deleted file mode 100755 index 50047db..0000000 --- a/test/offered_services_info_test/offered_services_info_test_local_starter.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -FAIL=0 - -cat < should be -# rejected and an error message should be printed. -# * Message exchange with client application should not be interrupted. - -# Array for client pids -CLIENT_PIDS=() -export VSOMEIP_CONFIGURATION=offered_services_info_test_local.json -# Start the services (routingmanagerd as app name) -./offered_services_info_test_service 1 & #routingmanagerd as app name -PID_SERVICE_ONE=$! -./offered_services_info_test_client METHODCALL & -CLIENT_PIDS+=($!) - -# Wait until all clients are finished -for job in ${CLIENT_PIDS[*]} -do - # Fail gets incremented if a client exits with a non-zero exit code - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill $PID_SERVICE_ONE -sleep 1 - - -# Check if everything went well -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/offered_services_info_test/offered_services_info_test_service.cpp b/test/offered_services_info_test/offered_services_info_test_service.cpp deleted file mode 100644 index a77b074..0000000 --- a/test/offered_services_info_test/offered_services_info_test_service.cpp +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#ifdef ANDROID -#include "../../configuration/include/internal_android.hpp" -#else -#include "../../configuration/include/internal.hpp" -#endif // ANDROID - -#include "offered_services_info_test_globals.hpp" - -static std::string service_number; -std::map> all_offered_services; -std::map> local_offered_services; -std::map> remote_offered_services; - - -class offer_test_service { -public: - offer_test_service(struct offer_test::service_info _service_info, struct offer_test::service_info _remote_service_info) : - service_info_(_service_info), - remote_service_info_(_remote_service_info), - // service with number 1 uses "routingmanagerd" as application name - // this way the same json file can be reused for all local tests - // including the ones with routingmanagerd - app_(vsomeip::runtime::get()->create_application( - (service_number == "1") ? "routingmanagerd" : - "offered_services_info_test_service" + service_number)), - wait_until_registered_(true), - shutdown_method_called_(false), - offer_thread_(std::bind(&offer_test_service::run, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&offer_test_service::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.method_id, - std::bind(&offer_test_service::on_request, this, - std::placeholders::_1)); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.shutdown_method_id, - std::bind(&offer_test_service::on_shutdown_method_called, this, - std::placeholders::_1)); - app_->start(); - } - - ~offer_test_service() { - offer_thread_.join(); - } - - void offer() { - //offer local services - app_->offer_service(service_info_.service_id, service_info_.instance_id); - local_offered_services[service_info_.service_id].insert(service_info_.instance_id); - all_offered_services[service_info_.service_id].insert(service_info_.instance_id); - - app_->offer_service(service_info_.service_id, (vsomeip::instance_t)(service_info_.instance_id + 1)); - local_offered_services[service_info_.service_id].insert((vsomeip::instance_t)(service_info_.instance_id + 1)); - all_offered_services[service_info_.service_id].insert((vsomeip::instance_t)(service_info_.instance_id + 1)); - - // offer remote service ID 0x2222 instance ID 0x2 (port configuration added to json file) - app_->offer_service(remote_service_info_.service_id, remote_service_info_.instance_id); // reliable and unreliable port - remote_offered_services[remote_service_info_.service_id].insert(remote_service_info_.instance_id); - all_offered_services[remote_service_info_.service_id].insert(remote_service_info_.instance_id); - - - app_->offer_service((vsomeip::service_t)(remote_service_info_.service_id + 1), (vsomeip::instance_t)(remote_service_info_.instance_id + 1)); // only reliable port - remote_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 1)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 1)); - all_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 1)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 1)); - - - app_->offer_service((vsomeip::service_t)(remote_service_info_.service_id + 2), (vsomeip::instance_t)(remote_service_info_.instance_id + 2)); // only unreliable port - remote_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 2)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 2)); - all_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 2)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 2)); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_request(const std::shared_ptr &_message) { - app_->send(vsomeip::runtime::get()->create_response(_message)); - } - - void on_shutdown_method_called(const std::shared_ptr &_message) { - (void)_message; - shutdown_method_called_ = true; - - app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); - app_->stop_offer_service(service_info_.service_id, (vsomeip::instance_t)(service_info_.instance_id + 1)); - - app_->stop_offer_service(remote_service_info_.service_id, remote_service_info_.instance_id); // reliable and unreliable port - app_->stop_offer_service((vsomeip::service_t)(remote_service_info_.service_id + 1), (vsomeip::instance_t)(remote_service_info_.instance_id + 1)); // only reliable port - app_->stop_offer_service((vsomeip::service_t)(remote_service_info_.service_id + 2), (vsomeip::instance_t)(remote_service_info_.instance_id + 2)); // only unreliable port - - app_->clear_all_handler(); - app_->stop(); - } - - void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - VSOMEIP_INFO << "TEST LOCAL SERVICES"; - app_->get_offered_services_async(vsomeip::offer_type_e::OT_LOCAL, std::bind(&offer_test_service::on_offered_services_local, this, std::placeholders::_1)); - - if (std::future_status::timeout == all_callbacks_received_.get_future().wait_for(std::chrono::seconds(15))) { - ADD_FAILURE() << "Didn't receive all callbacks within time"; - } - - while(!shutdown_method_called_) { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - } - - - void on_offered_services_local( const std::vector> &_services) { - std::cout << "ON OFFERED SERVICES LOCAL CALLBACK START" << std::endl; - EXPECT_EQ(2u, _services.size()); - bool local_service_test_failed(true); - uint16_t i=0; - for (auto its_pair : _services) { - local_service_test_failed = true; - std::cout << "CALLBACK VALUE -> Service: "<< std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; - auto found_service = local_offered_services.find(its_pair.first); - if (found_service != local_offered_services.end()) { - auto found_instance = found_service->second.find(its_pair.second); - if (found_instance != found_service->second.end()) { - i++; - local_service_test_failed = false; - } - } - EXPECT_FALSE(local_service_test_failed); - } - EXPECT_EQ(offer_test::num_local_offered_services, i); - - std::cout << "ON OFFERED SERVICES LOCAL CALLBACK END" << std::endl; - - VSOMEIP_INFO << "TEST REMOTE SERVICES"; - app_->get_offered_services_async(vsomeip::offer_type_e::OT_REMOTE, std::bind(&offer_test_service::on_offered_services_remote, this, std::placeholders::_1)); - } - - - void on_offered_services_remote( const std::vector> &_services) { - std::cout << "ON OFFERED SERVICES REMOTE CALLBACK START" << std::endl; - EXPECT_EQ(3u, _services.size()); - bool remote_service_test_failed(true); - uint16_t i=0; - for (auto its_pair : _services) { - remote_service_test_failed = true; - std::cout << "CALLBACK VALUE -> Service: " << std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; - auto found_service = remote_offered_services.find(its_pair.first); - if (found_service != remote_offered_services.end()) { - auto found_instance = found_service->second.find(its_pair.second); - if (found_instance != found_service->second.end()) { - i++; - remote_service_test_failed = false; - } - } - EXPECT_FALSE(remote_service_test_failed); - } - EXPECT_EQ(offer_test::num_remote_offered_services, i); - - std::cout << "ON OFFERED SERVICES REMOTE CALLBACK END" << std::endl; - - VSOMEIP_INFO << "TEST ALL SERVICES"; - app_->get_offered_services_async(vsomeip::offer_type_e::OT_ALL, std::bind(&offer_test_service::on_offered_services_all, this, std::placeholders::_1)); - } - - - void on_offered_services_all( const std::vector> &_services) { - std::cout << "ON OFFERED SERVICES ALL CALLBACK START" << std::endl; - EXPECT_EQ(5u, _services.size()); - bool all_service_test_failed(true); - uint16_t i=0; - for (auto its_pair : _services) { - all_service_test_failed = true; - std::cout << "CALLBACK VALUE -> Service: " << std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; - auto found_service = all_offered_services.find(its_pair.first); - if (found_service != all_offered_services.end()) { - auto found_instance = found_service->second.find(its_pair.second); - if (found_instance != found_service->second.end()) { - i++; - all_service_test_failed = false; - } - } - EXPECT_FALSE(all_service_test_failed); - } - EXPECT_EQ(offer_test::num_all_offered_services, i); - std::cout << "ON OFFERED SERVICES ALL CALLBACK END" << std::endl; - all_callbacks_received_.set_value(); - } - -private: - struct offer_test::service_info service_info_; - struct offer_test::service_info remote_service_info_; - std::shared_ptr app_; - - bool wait_until_registered_; - std::mutex mutex_; - std::condition_variable condition_; - std::atomic shutdown_method_called_; - std::promise all_callbacks_received_; - std::thread offer_thread_; -}; - -TEST(someip_offered_services_info_test, check_offered_services_as_rm_impl) -{ - offer_test_service its_sample(offer_test::service, offer_test::remote_service); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if(argc < 2) { - std::cerr << "Please specify a service number, like: " << argv[0] << " 2" << std::endl; - return 1; - } - - service_number = std::string(argv[1]); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/payload_tests/conf/external_local_payload_test_client_external.json.in b/test/payload_tests/conf/external_local_payload_test_client_external.json.in deleted file mode 100644 index 0abaea2..0000000 --- a/test/payload_tests/conf/external_local_payload_test_client_external.json.in +++ /dev/null @@ -1,53 +0,0 @@ -{ - "unicast" : "@TEST_IP_SLAVE@", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "true", - "path" : "/var/log/vsomeip.log" - }, - - "dlt" : "true" - }, - - "applications" : - [ - { - "name" : "external_local_payload_test_client_external", - "id" : "0x1343" - } - ], - - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509", - "reliable" : - { - "port" : "30510", - "enable-magic-cookies" : "false" - } - } - ], - "npdu-default-timings" : { - "debounce-time-request" : "0", - "debounce-time-response" : "0", - "max-retention-time-request" : "0", - "max-retention-time-response" : "0" - }, - "routing" : "external_local_payload_test_client_external", - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30491", - "protocol" : "udp" - } -} diff --git a/test/payload_tests/conf/external_local_payload_test_client_local.json.in b/test/payload_tests/conf/external_local_payload_test_client_local.json.in deleted file mode 100644 index 1f4fd6d..0000000 --- a/test/payload_tests/conf/external_local_payload_test_client_local.json.in +++ /dev/null @@ -1,54 +0,0 @@ -{ - "unicast" : "@TEST_IP_MASTER@", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "true", - "path" : "/var/log/vsomeip.log" - }, - - "dlt" : "true" - }, - - "applications" : - [ - { - "name" : "external_local_payload_test_client_local", - "id" : "0x1343" - } - ], - - - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509", - "reliable" : - { - "port" : "30510", - "enable-magic-cookies" : "false" - } - } - ], - "npdu-default-timings" : { - "debounce-time-request" : "0", - "debounce-time-response" : "0", - "max-retention-time-request" : "0", - "max-retention-time-response" : "0" - }, - "routing" : "external_local_payload_test_service", - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30491", - "protocol" : "udp" - } -} diff --git a/test/payload_tests/conf/external_local_payload_test_service.json.in b/test/payload_tests/conf/external_local_payload_test_service.json.in deleted file mode 100644 index aaeae82..0000000 --- a/test/payload_tests/conf/external_local_payload_test_service.json.in +++ /dev/null @@ -1,51 +0,0 @@ -{ - "unicast" : "@TEST_IP_MASTER@", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "false", - "path" : "/tmp/vsomeip.log" - }, - - "dlt" : "false" - }, - - "applications" : - [ - { - "name" : "external_local_payload_test_service", - "id" : "0x1277" - } - ], - - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678", - "unreliable" : "30509", - "reliable" : - { - "port" : "30510", - "enable-magic-cookies" : "false" - } - } - ], - "npdu-default-timings" : { - "debounce-time-request" : "0", - "debounce-time-response" : "0", - "max-retention-time-request" : "0", - "max-retention-time-response" : "0" - }, - "routing" : "external_local_payload_test_service", - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp" - } -} diff --git a/test/payload_tests/external_local_payload_test_client_external_start.sh b/test/payload_tests/external_local_payload_test_client_external_start.sh deleted file mode 100755 index 5f6b7ea..0000000 --- a/test/payload_tests/external_local_payload_test_client_external_start.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_external -export VSOMEIP_CONFIGURATION=external_local_payload_test_client_external.json -./payload_test_client --udp --max-payload-size UDP -# We sleep to let the service restart with --tcp option so we can test -# communication via TCP. -sleep 5 -./payload_test_client --tcp --max-payload-size TCP diff --git a/test/payload_tests/external_local_payload_test_client_external_starter.sh b/test/payload_tests/external_local_payload_test_client_external_starter.sh deleted file mode 100755 index f6c2744..0000000 --- a/test/payload_tests/external_local_payload_test_client_external_starter.sh +++ /dev/null @@ -1,124 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -FAIL=0 - -# Parameter 1: the pid to check -# Parameter 2: number of TCP/UDP sockets the process should have open -check_tcp_udp_sockets_are_open () -{ - # Check that the passed pid/process does listen on at least one TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -lt $2 ] - then - ((FAIL+=1)) - fi -} - -# Parameter 1: the pid to check -check_tcp_udp_sockets_are_closed () -{ - # Check that the passed pid/process does not listen on any TCP/UDP socket - # or has any active connection via a TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] - then - ((FAIL+=1)) - fi - - SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] - then - ((FAIL+=1)) - fi -} - -# Start the service for payload test with UDP -export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service -export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json -./payload_test_service --udp & -SERIVCE_PID=$! - -# Display a message to show the user that he must now call the external client -# to finish the test successfully -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting external local payload on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./external_local_payload_test_client_external_start.sh\"" & - echo "remote ssh job id: $!" -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_payload_test_client_external_start.sh" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./external_local_payload_test_client_external_start.sh\" >> $WS_ROOT/slave_test_output 2>&1" & - -else -cat < /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -lt $2 ] - then - ((FAIL+=1)) - fi -} - -# Parameter 1: the pid to check -check_tcp_udp_sockets_are_closed () -{ - # Check that the passed pid/process does not listen on any TCP/UDP socket - # or has any active connection via a TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] - then - ((FAIL+=1)) - fi - - SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] - then - ((FAIL+=1)) - fi -} - -# Start the service -export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service -export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json -./payload_test_service & -SERIVCE_PID=$! -sleep 1; - -# The service should listen on a TCP and UDP socket now -check_tcp_udp_sockets_are_open $SERIVCE_PID 2 - -# Start the client which sends messages over local UDS -export VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_local -export VSOMEIP_CONFIGURATION=external_local_payload_test_client_local.json -./payload_test_client --dont-shutdown-service & -CLIENT_PID=$! -sleep 1 - -check_tcp_udp_sockets_are_open $SERIVCE_PID 2 -check_tcp_udp_sockets_are_closed $CLIENT_PID - -# Wait until client is finished -wait $CLIENT_PID || ((FAIL+=1)) - -# Display a message to show the user that he must now call the external client -# to finish the test successfully -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting external local payload on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./external_local_payload_test_client_external_start.sh\"" & - echo "remote ssh job id: $!" -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_payload_test_client_external_start.sh" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./external_local_payload_test_client_external_start.sh\" >> $WS_ROOT/slave_test_output 2>&1" & - -else -cat < /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -lt $2 ] - then - ((FAIL+=1)) - fi -} - -# Parameter 1: the pid to check -check_tcp_udp_sockets_are_closed () -{ - # Check that the passed pid/process does not listen on any TCP/UDP socket - # or has any active connection via a TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] - then - ((FAIL+=1)) - fi - - SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] - then - ((FAIL+=1)) - fi -} - -# Start the service -export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service -export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json -./payload_test_service & -SERIVCE_PID=$! -sleep 1; - -# The service should listen on a TCP and UDP socket now -check_tcp_udp_sockets_are_open $SERIVCE_PID 2 - -# Start the client -export VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_local -export VSOMEIP_CONFIGURATION=external_local_payload_test_client_local.json -./payload_test_client & -CLIENT_PID=$! - -# The service should still listen on a TCP and UDP socket now -check_tcp_udp_sockets_are_open $SERIVCE_PID 2 -# The client should use the shortcut over a local UDS instead of TCP/UDP, -# therefore he shouldn't have any open TCP/UDP sockets -check_tcp_udp_sockets_are_closed $CLIENT_PID - -if [ ! -z "$USE_DOCKER" ]; then - FAIL=0 -fi - -# Wait until client and service are finished -for job in $(jobs -p) -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if client and server both exited sucessfully -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/payload_tests/external_local_payload_test_service_client_external_start.sh b/test/payload_tests/external_local_payload_test_service_client_external_start.sh deleted file mode 100755 index 046d50b..0000000 --- a/test/payload_tests/external_local_payload_test_service_client_external_start.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service -export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json -./payload_test_service --udp -# After payload was measured with UDP the client will restart and measure -# throughput with TCP -./payload_test_service --tcp \ No newline at end of file diff --git a/test/payload_tests/external_local_payload_test_service_start.sh b/test/payload_tests/external_local_payload_test_service_start.sh deleted file mode 100755 index 90b1b38..0000000 --- a/test/payload_tests/external_local_payload_test_service_start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service -export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json -./payload_test_service diff --git a/test/payload_tests/local_payload_test_client.json b/test/payload_tests/local_payload_test_client.json deleted file mode 100644 index 24fa1fa..0000000 --- a/test/payload_tests/local_payload_test_client.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "unicast" : "127.0.0.1", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "true", - "path" : "/var/log/vsomeip.log" - }, - - "dlt" : "true" - }, - - "applications" : - [ - { - "name" : "local_payload_test_client", - "id" : "0x1343" - } - ], - "services" : - [ - ], - - "routing" : "local_payload_test_service", - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30491", - "protocol" : "udp" - } -} diff --git a/test/payload_tests/local_payload_test_client_start.sh b/test/payload_tests/local_payload_test_client_start.sh deleted file mode 100755 index 975be2a..0000000 --- a/test/payload_tests/local_payload_test_client_start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=local_payload_test_client -export VSOMEIP_CONFIGURATION=local_payload_test_client.json -./payload_test_client diff --git a/test/payload_tests/local_payload_test_huge_payload_starter.sh b/test/payload_tests/local_payload_test_huge_payload_starter.sh deleted file mode 100755 index c230891..0000000 --- a/test/payload_tests/local_payload_test_huge_payload_starter.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -FAIL=0 - -# Start the service -export VSOMEIP_APPLICATION_NAME=local_payload_test_service -export VSOMEIP_CONFIGURATION=local_payload_test_service.json -./payload_test_service & -SERIVCE_PID=$! -sleep 1; - -# Start the client -export VSOMEIP_APPLICATION_NAME=local_payload_test_client -export VSOMEIP_CONFIGURATION=local_payload_test_client.json -./payload_test_client --number-of-messages 100 --max-payload-size 10485760 & -CLIENT_PID=$! - -# Wait until client and service are finished -for job in $(jobs -p) -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if client and server both exited sucessfully and the service didnt't -# have any open tcp/udp sockets -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/payload_tests/local_payload_test_service.json b/test/payload_tests/local_payload_test_service.json deleted file mode 100644 index b5c83a6..0000000 --- a/test/payload_tests/local_payload_test_service.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "unicast" : "127.0.0.1", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "false", - "path" : "/tmp/vsomeip.log" - }, - - "dlt" : "false" - }, - - "applications" : - [ - { - "name" : "local_payload_test_service", - "id" : "0x1277" - } - ], - - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678" - } - ], - - "routing" : "local_payload_test_service", - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp" - } -} diff --git a/test/payload_tests/local_payload_test_service_start.sh b/test/payload_tests/local_payload_test_service_start.sh deleted file mode 100755 index cc67f54..0000000 --- a/test/payload_tests/local_payload_test_service_start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=local_payload_test_service -export VSOMEIP_CONFIGURATION=local_payload_test_service.json -./payload_test_service diff --git a/test/payload_tests/local_payload_test_starter.sh b/test/payload_tests/local_payload_test_starter.sh deleted file mode 100755 index abc4577..0000000 --- a/test/payload_tests/local_payload_test_starter.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -FAIL=0 - -# Parameter 1: the pid to check -check_tcp_udp_sockets_are_closed () -{ - # Check that the service does not listen on any TCP/UDP socket - # or has any active connection via a TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] - then - ((FAIL+=1)) - fi - - SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] - then - ((FAIL+=1)) - fi -} - -# Start the service -export VSOMEIP_APPLICATION_NAME=local_payload_test_service -export VSOMEIP_CONFIGURATION=local_payload_test_service.json -./payload_test_service & -SERIVCE_PID=$! -sleep 1; - -check_tcp_udp_sockets_are_closed $SERIVCE_PID - -# Start the client -export VSOMEIP_APPLICATION_NAME=local_payload_test_client -export VSOMEIP_CONFIGURATION=local_payload_test_client.json -./payload_test_client & -CLIENT_PID=$! - -check_tcp_udp_sockets_are_closed $SERIVCE_PID -check_tcp_udp_sockets_are_closed $CLIENT_PID - -# Wait until client and service are finished -for job in $(jobs -p) -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if client and server both exited sucessfully and the service didnt't -# have any open tcp/udp sockets -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/payload_tests/payload_test_client.cpp b/test/payload_tests/payload_test_client.cpp deleted file mode 100644 index 0a9708f..0000000 --- a/test/payload_tests/payload_test_client.cpp +++ /dev/null @@ -1,415 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "payload_test_client.hpp" - -enum class payloadsize - : std::uint8_t - { - UDS, TCP, UDP, USER_SPECIFIED -}; - -// this variables are changed via cmdline parameters -static bool use_tcp = false; -static bool call_service_sync = true; -static std::uint32_t sliding_window_size = vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS; -static payloadsize max_payload_size = payloadsize::UDS; -static bool shutdown_service_at_end = true; -static std::uint32_t user_defined_max_payload; -static std::uint32_t number_of_messages_to_send = 0; - -payload_test_client::payload_test_client( - bool _use_tcp, - bool _call_service_sync, - std::uint32_t _sliding_window_size) : - app_(vsomeip::runtime::get()->create_application()), - request_(vsomeip::runtime::get()->create_request(_use_tcp)), - call_service_sync_(_call_service_sync), - sliding_window_size_(_sliding_window_size), - blocked_(false), - is_available_(false), - number_of_messages_to_send_(number_of_messages_to_send ? number_of_messages_to_send : vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS), - number_of_sent_messages_(0), - number_of_sent_messages_total_(0), - number_of_acknowledged_messages_(0), - current_payload_size_(1), - all_msg_acknowledged_(false), - sender_(std::bind(&payload_test_client::run, this)) -{ -} - -bool payload_test_client::init() -{ - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - - app_->register_state_handler( - std::bind(&payload_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, - std::bind(&payload_test_client::on_message, this, - std::placeholders::_1)); - - app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - std::bind(&payload_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - return true; -} - -void payload_test_client::start() -{ - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void payload_test_client::stop() -{ - VSOMEIP_INFO << "Stopping..."; - // shutdown the service - if(shutdown_service_at_end) - { - shutdown_service(); - } - app_->clear_all_handler(); -} - -void payload_test_client::shutdown_service() -{ - request_->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - request_->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - request_->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); - app_->send(request_); -} - -void payload_test_client::join_sender_thread() -{ - sender_.join(); -} - -void payload_test_client::on_state(vsomeip::state_type_e _state) -{ - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); - } -} - -void payload_test_client::on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) -{ - VSOMEIP_INFO << "Service [" << std::setw(4) << std::setfill('0') << std::hex - << _service << "." << _instance << "] is " - << (_is_available ? "available." : "NOT available."); - - if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service - && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) - { - if(is_available_ && !_is_available) - { - is_available_ = false; - } - else if(_is_available && !is_available_) - { - is_available_ = true; - send(); - } - } -} - -void payload_test_client::on_message(const std::shared_ptr& _response) -{ - number_of_acknowledged_messages_++; - - ASSERT_EQ(_response->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID); - ASSERT_EQ(_response->get_instance(), vsomeip_test::TEST_SERVICE_INSTANCE_ID); - - if(call_service_sync_) - { - // We notify the sender thread every time a message was acknowledged - { - std::lock_guard lk(all_msg_acknowledged_mutex_); - all_msg_acknowledged_ = true; - } - all_msg_acknowledged_cv_.notify_one(); - } - else - { - // We notify the sender thread only if all sent messages have been acknowledged - if(number_of_acknowledged_messages_ == number_of_messages_to_send_) - { - std::lock_guard lk(all_msg_acknowledged_mutex_); - number_of_acknowledged_messages_ = 0; - all_msg_acknowledged_ = true; - all_msg_acknowledged_cv_.notify_one(); - } - else if(number_of_acknowledged_messages_ % sliding_window_size_ == 0) - { - std::lock_guard lk(all_msg_acknowledged_mutex_); - all_msg_acknowledged_ = true; - all_msg_acknowledged_cv_.notify_one(); - } - } -} - -void payload_test_client::send() -{ - std::lock_guard its_lock(mutex_); - blocked_ = true; - condition_.notify_one(); -} - -void payload_test_client::run() -{ - std::unique_lock its_lock(mutex_); - while (!blocked_) - { - condition_.wait(its_lock); - } - - request_->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - request_->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - request_->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); - - // lock the mutex - std::unique_lock lk(all_msg_acknowledged_mutex_); - - std::uint32_t max_allowed_payload = get_max_allowed_payload(); - - std::shared_ptr payload = vsomeip::runtime::get()->create_payload(); - std::vector payload_data; - bool reached_peak = false; - for(;;) - { - payload_data.assign(current_payload_size_ , vsomeip_test::PAYLOAD_TEST_DATA); - payload->set_data(payload_data); - request_->set_payload(payload); - - watch_.reset(); - watch_.start(); - - call_service_sync_ ? send_messages_sync(lk) : send_messages_async(lk); - - watch_.stop(); - print_throughput(); - - // Increase array size for next iteration - if(!reached_peak) { - current_payload_size_ *= 2; - } else { - current_payload_size_ /= 2; - } - - if(!reached_peak && current_payload_size_ > max_allowed_payload) - { - current_payload_size_ = max_allowed_payload; - reached_peak = true; - } else if(reached_peak && current_payload_size_ <= 1) { - break; - } - } - blocked_ = false; - - stop(); - std::thread t1([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 5));}); - t1.join(); - app_->stop(); - std::thread t([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 5));}); - t.join(); -} - - -std::uint32_t payload_test_client::get_max_allowed_payload() -{ - std::uint32_t payload; - switch (max_payload_size) - { - case payloadsize::UDS: - // TODO - payload = 1024 * 32 - 16; - break; - case payloadsize::TCP: - // TODO - payload = 4095 - 16; - break; - case payloadsize::UDP: - payload = VSOMEIP_MAX_UDP_MESSAGE_SIZE - 16; - break; - case payloadsize::USER_SPECIFIED: - payload = user_defined_max_payload; - break; - default: - payload = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE; - break; - } - return payload; -} - -void payload_test_client::send_messages_sync(std::unique_lock& lk) -{ - for (number_of_sent_messages_ = 0; - number_of_sent_messages_ < number_of_messages_to_send_; - number_of_sent_messages_++, number_of_sent_messages_total_++) - { - app_->send(request_); - // wait until the send messages has been acknowledged - // as long we wait lk is released; after wait returns lk is reacquired - all_msg_acknowledged_cv_.wait(lk, [&] - { return all_msg_acknowledged_;}); - // Reset condition variable (lk is locked again here) - all_msg_acknowledged_ = false; - } -} - -void payload_test_client::send_messages_async(std::unique_lock& lk) -{ - for (number_of_sent_messages_ = 0; - number_of_sent_messages_ < number_of_messages_to_send_; - number_of_sent_messages_++, number_of_sent_messages_total_++) - { - app_->send(request_); - - if((number_of_sent_messages_+1) % sliding_window_size_ == 0) - { - // wait until all send messages have been acknowledged - // as long we wait lk is released; after wait returns lk is reacquired - all_msg_acknowledged_cv_.wait(lk, [&] - { return all_msg_acknowledged_;}); - - // Reset condition variable - all_msg_acknowledged_ = false; - } - } -} - -void payload_test_client::print_throughput() -{ - constexpr std::uint32_t usec_per_sec = 1000000; - stop_watch::usec_t time_needed = watch_.get_total_elapsed_microseconds(); - stop_watch::usec_t time_per_message = time_needed / number_of_sent_messages_; - std::double_t calls_per_sec = number_of_sent_messages_ - * (usec_per_sec / static_cast(time_needed)); - std::double_t mbyte_per_sec = ((number_of_sent_messages_ - * current_payload_size_) - / (static_cast(time_needed) / usec_per_sec)) / (1024*1024); - - VSOMEIP_INFO<< "[ Payload Test ] : :" - << "Payload size [byte]: " << std::dec << std::setw(8) << std::setfill('0') << current_payload_size_ - << " Messages sent: " << std::dec << std::setw(8) << std::setfill('0') << number_of_sent_messages_ - << " Meantime/message [usec]: " << std::dec << std::setw(8) << std::setfill('0') << time_per_message - << " Calls/sec: " << std::dec << std::setw(8) << std::setfill('0') << calls_per_sec - << " MiB/sec: " << std::dec << std::setw(8) << std::setfill('0') << mbyte_per_sec; -} - -TEST(someip_payload_test, send_different_payloads) -{ - payload_test_client test_client_(use_tcp, call_service_sync, sliding_window_size); - if (test_client_.init()) { - test_client_.start(); - test_client_.join_sender_thread(); - } -} - - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - std::string tcp_enable("--tcp"); - std::string udp_enable("--udp"); - std::string sync_enable("--sync"); - std::string async_enable("--async"); - std::string sliding_window_size_param("--sliding-window-size"); - std::string max_payload_size_param("--max-payload-size"); - std::string shutdown_service_disable_param("--dont-shutdown-service"); - std::string numbers_of_messages("--number-of-messages"); - std::string help("--help"); - - int i = 1; - while (i < argc) - { - if(tcp_enable == argv[i]) - { - use_tcp = true; - } - else if(udp_enable == argv[i]) - { - use_tcp = false; - } - else if(sync_enable == argv[i]) - { - call_service_sync = true; - } - else if(async_enable == argv[i]) - { - call_service_sync = false; - } - else if(sliding_window_size_param == argv[i] && i + 1 < argc) - { - i++; - std::stringstream converter(argv[i]); - converter >> sliding_window_size; - } - else if(max_payload_size_param == argv[i] && i + 1 < argc) - { - i++; - if(std::string("UDS") == argv[i]) - { - max_payload_size = payloadsize::UDS; - } - else if(std::string("TCP") == argv[i]) - { - max_payload_size = payloadsize::TCP; - } - else if(std::string("UDP") == argv[i]) - { - max_payload_size = payloadsize::UDP; - } - else { - max_payload_size = payloadsize::USER_SPECIFIED; - std::stringstream converter(argv[i]); - converter >> user_defined_max_payload; - } - } - else if (numbers_of_messages == argv[i]) { - i++; - std::stringstream converter(argv[i]); - converter >> number_of_messages_to_send; - } - else if(shutdown_service_disable_param == argv[i]) - { - shutdown_service_at_end = false; - } - else if(help == argv[i]) - { - VSOMEIP_INFO << "Parameters:\n" - << "--tcp: Send messages via TCP\n" - << "--udp: Send messages via UDP (default)\n" - << "--sync: Wait for acknowledge before sending next message (default)\n" - << "--async: Send multiple messages w/o waiting for" - " acknowledge of service\n" - << "--sliding-window-size: Number of messages to send before waiting " - "for acknowledge of service. Default: " << sliding_window_size << "\n" - << "--max-payload-size: limit the maximum payloadsize of send requests. One of {" - "UDS (=" << VSOMEIP_MAX_LOCAL_MESSAGE_SIZE << "byte), " - "UDP (=" << VSOMEIP_MAX_UDP_MESSAGE_SIZE << "byte), " - "TCP (=" << VSOMEIP_MAX_TCP_MESSAGE_SIZE << "byte)}, default: UDS\n" - << "--dont-shutdown-service: Don't shutdown the service upon " - "finishing of the payload test\n" - << "--number-of-messages: Number of messages to send per payload size iteration\n" - << "--help: print this help"; - } - i++; - } - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/payload_tests/payload_test_client.hpp b/test/payload_tests/payload_test_client.hpp deleted file mode 100644 index 2757d00..0000000 --- a/test/payload_tests/payload_test_client.hpp +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef PAYLOADTESTCLIENT_HPP_ -#define PAYLOADTESTCLIENT_HPP_ - -#include - -#include - -#include -#include -#include -#include -#include - -#include "../someip_test_globals.hpp" - -#include "stopwatch.hpp" - -class payload_test_client -{ -public: - payload_test_client(bool _use_tcp, bool _call_service_sync, std::uint32_t _sliding_window_size); - bool init(); - void start(); - void stop(); - void join_sender_thread(); - void on_state(vsomeip::state_type_e _state); - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available); - void on_message(const std::shared_ptr &_response); - void send(); - void run(); - -private: - void print_throughput(); - void send_messages_sync(std::unique_lock& lk); - void send_messages_async(std::unique_lock& lk); - void shutdown_service(); - std::uint32_t get_max_allowed_payload(); - -private: - std::shared_ptr app_; - std::shared_ptr request_; - bool call_service_sync_; - std::uint32_t sliding_window_size_; - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - bool is_available_; - const std::uint32_t number_of_messages_to_send_; - std::uint32_t number_of_sent_messages_; - std::uint32_t number_of_sent_messages_total_; - std::uint32_t number_of_acknowledged_messages_; - - std::uint32_t current_payload_size_; - - stop_watch watch_; - - bool all_msg_acknowledged_; - std::mutex all_msg_acknowledged_mutex_; - std::condition_variable all_msg_acknowledged_cv_; - - std::thread sender_; - -}; - -#endif /* PAYLOADTESTCLIENT_HPP_ */ diff --git a/test/payload_tests/payload_test_service.cpp b/test/payload_tests/payload_test_service.cpp deleted file mode 100644 index 18935f9..0000000 --- a/test/payload_tests/payload_test_service.cpp +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "payload_test_service.hpp" - -// this variables are changed via cmdline parameters - -static bool check_payload = true; - -payload_test_service::payload_test_service() : - app_(vsomeip::runtime::get()->create_application()), - is_registered_(false), - blocked_(false), - number_of_received_messages_(0), - offer_thread_(std::bind(&payload_test_service::run, this)) -{ -} - -bool payload_test_service::init() -{ - std::lock_guard its_lock(mutex_); - - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, - std::bind(&payload_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, - std::bind(&payload_test_service::on_message_shutdown, this, - std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&payload_test_service::on_state, this, - std::placeholders::_1)); - return true; -} - -void payload_test_service::start() -{ - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void payload_test_service::stop() -{ - VSOMEIP_INFO << "Stopping..."; - app_->clear_all_handler(); - app_->stop(); -} - -void payload_test_service::join_offer_thread() -{ - offer_thread_.join(); -} - -void payload_test_service::offer() -{ - app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void payload_test_service::stop_offer() -{ - app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void payload_test_service::on_state(vsomeip::state_type_e _state) -{ - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : - "deregistered."); - - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - if(!is_registered_) - { - is_registered_ = true; - std::lock_guard its_lock(mutex_); - blocked_ = true; - // "start" the run method thread - condition_.notify_one(); - } - } - else - { - is_registered_ = false; - } -} - -void payload_test_service::on_message(const std::shared_ptr& _request) -{ - number_of_received_messages_++; - if(number_of_received_messages_ % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS == 0) - { - VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _request->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _request->get_session() << "] payload size [byte]:" - << std::dec << _request->get_payload()->get_length(); - } - - ASSERT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _request->get_service()); - ASSERT_EQ(vsomeip_test::TEST_SERVICE_METHOD_ID, _request->get_method()); - - // Check the protocol version this shall be set to 0x01 according to the spec. - // TR_SOMEIP_00052 - ASSERT_EQ(0x01, _request->get_protocol_version()); - // Check the message type this shall be 0xx (REQUEST) according to the spec. - // TR_SOMEIP_00055 - ASSERT_EQ(vsomeip::message_type_e::MT_REQUEST, _request->get_message_type()); - - if (check_payload) { - std::shared_ptr pl = _request->get_payload(); - vsomeip::byte_t* pl_ptr = pl->get_data(); - for (vsomeip::length_t i = 0; i < pl->get_length(); i++) - { - ASSERT_EQ(vsomeip_test::PAYLOAD_TEST_DATA, *(pl_ptr+i)); - } - } - - // send response - std::shared_ptr its_response = - vsomeip::runtime::get()->create_response(_request); - - app_->send(its_response); -} - -void payload_test_service::on_message_shutdown( - const std::shared_ptr& _request) -{ - (void)_request; - VSOMEIP_INFO << "Shutdown method was called, going down now."; - stop(); -} - -void payload_test_service::run() -{ - std::unique_lock its_lock(mutex_); - while (!blocked_) - condition_.wait(its_lock); - - offer(); -} - -TEST(someip_payload_test, send_response_for_every_request) -{ - payload_test_service test_service; - if (test_service.init()) { - test_service.start(); - test_service.join_offer_thread(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - std::string help("--help"); - std::string check("--do-not-check-payload"); - - int i = 1; - while (i < argc) - { - if(help == argv[i]) - { - VSOMEIP_INFO << "Parameters:\n" - << "--help: print this help\n" - << "--do-not-check-payload: Don't verify payload data " - << "-> Use this flag for performance measurements!"; - } else if (check == argv[i]) { - check_payload = false; - } - i++; - } - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/payload_tests/payload_test_service.hpp b/test/payload_tests/payload_test_service.hpp deleted file mode 100644 index 9054fd9..0000000 --- a/test/payload_tests/payload_test_service.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef PAYLOADTESTSERVICE_HPP_ -#define PAYLOADTESTSERVICE_HPP_ -#include - -#include - -#include -#include -#include -#include - -#include "../someip_test_globals.hpp" - -class payload_test_service -{ -public: - payload_test_service(); - bool init(); - void start(); - void stop(); - void offer(); - void stop_offer(); - void join_offer_thread(); - void on_state(vsomeip::state_type_e _state); - void on_message(const std::shared_ptr &_request); - void on_message_shutdown(const std::shared_ptr &_request); - void run(); - -private: - std::shared_ptr app_; - bool is_registered_; - - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - std::uint32_t number_of_received_messages_; - std::thread offer_thread_; -}; - -#endif /* PAYLOADTESTSERVICE_HPP_ */ diff --git a/test/payload_tests/stopwatch.cpp b/test/payload_tests/stopwatch.cpp deleted file mode 100644 index 83506f4..0000000 --- a/test/payload_tests/stopwatch.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "stopwatch.hpp" - -#include -#include - - -#define USEC_PER_SEC 1000000ULL -#define NSEC_PER_USEC 1000ULL - - -stop_watch::usec_t stop_watch::get_total_elapsed_microseconds() const { - usec_t elapsed = total_elapsed_; - - if (started_) - elapsed += get_elapsed(); - - return elapsed; -} - -stop_watch::usec_t stop_watch::get_total_elapsed_seconds() const { - return get_total_elapsed_microseconds() / USEC_PER_SEC; -} - -stop_watch::usec_t stop_watch::now() { - struct timespec ts; - - const int ret = clock_gettime(CLOCK_MONOTONIC_RAW, &ts); - assert(!ret); - static_cast(ret); // prevent warning in release build - - return (usec_t) ts.tv_sec * USEC_PER_SEC + (usec_t) ts.tv_nsec / NSEC_PER_USEC; -} - diff --git a/test/payload_tests/stopwatch.hpp b/test/payload_tests/stopwatch.hpp deleted file mode 100644 index 5917e12..0000000 --- a/test/payload_tests/stopwatch.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef STOP_WATCH_H_ -#define STOP_WATCH_H_ - -#include - - -class stop_watch -{ -public: - typedef uint64_t usec_t; - - stop_watch() : - started_(false), - start_time_point_(0), - total_elapsed_(0) - { - } - - inline void reset() - { - started_ = false; - total_elapsed_ = 0; - } - - inline void start() - { - start_time_point_ = now(); - started_ = true; - } - - inline void stop() - { - total_elapsed_ += get_elapsed(); - started_ = false; - } - - usec_t get_total_elapsed_microseconds() const; - usec_t get_total_elapsed_seconds() const; - -private: - inline usec_t get_elapsed() const - { - return now() - start_time_point_; - } - - static usec_t now(); - - bool started_; - usec_t start_time_point_; - usec_t total_elapsed_; -}; - -#endif // STOP_WATCH_H_ diff --git a/test/pending_subscription_tests/conf/pending_subscription_test_master.json.in b/test/pending_subscription_tests/conf/pending_subscription_test_master.json.in deleted file mode 100644 index 5bcbe9a..0000000 --- a/test/pending_subscription_tests/conf/pending_subscription_test_master.json.in +++ /dev/null @@ -1,55 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"info", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications" : - [ - { - "name" : "pending_subscription_test_service", - "id" : "0xCAFE", - "max_dispatch_time" : "1000" - } - ], - "services": - [ - { - "service":"0x1122", - "instance":"0x0001", - "unreliable":"30001", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - }, - "events" : - [ - { - "event" : "0x1111", - "is_reliable" : "false" - }, - { - "event" : "0x1112", - "is_reliable" : "false" - } - ] - } - ], - "routing":"routingmanagerd", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.23.1", - "port":"30490", - "protocol":"udp", - "cyclic_offer_delay" : "1000" - } -} \ No newline at end of file diff --git a/test/pending_subscription_tests/conf/pending_subscription_test_master_starter.sh.in b/test/pending_subscription_tests/conf/pending_subscription_test_master_starter.sh.in deleted file mode 100755 index 298a3ea..0000000 --- a/test/pending_subscription_tests/conf/pending_subscription_test_master_starter.sh.in +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -FAIL=0 - -if [ $# -lt 1 ] -then - echo "Please pass a test mode to this script." - echo "For example: $0 SUSCRIBE" - echo "Valid subscription types include:" - echo " [SUBSCRIBE, SUBSCRIBE_UNSUBSCRIBE, UNSUBSCRIBE, SUBSCRIBE_UNSUBSCRIBE_NACK, SUBSCRIBE_UNSUBSCRIBE_SAME_PORT, SUBSCRIBE_RESUBSCRIBE_MIXED, SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE, REQUEST_TO_SD]" - exit 1 -fi -TESTMODE=$1 -export VSOMEIP_CONFIGURATION=pending_subscription_test_master.json -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! -# Start the services -./pending_subscription_test_service $1 & -PID_SERIVCE=$! - -sleep 1 - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "Waiting for 5s" - sleep 5 - echo "starting offer test on slave LXC offer_test_external_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./pending_subscription_test_sd_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $TESTMODE\"" & - echo "remote ssh pid: $!" -elif [ ! -z "$USE_DOCKER" ]; then - echo "Waiting for 5s" - sleep 5 - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./pending_subscription_test_sd_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $TESTMODE" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./pending_subscription_test_sd_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $TESTMODE\" >> $WS_ROOT/slave_test_output 2>&1" & - -else -cat < -#include -#include -#include -#include -#include - -#include - -#include - -#include - -#include "../../implementation/utility/include/byteorder.hpp" -#include "../../implementation/message/include/deserializer.hpp" -#include "../../implementation/service_discovery/include/service_discovery.hpp" -#include "../../implementation/service_discovery/include/message_impl.hpp" -#include "../../implementation/service_discovery/include/constants.hpp" -#include "../../implementation/service_discovery/include/enumeration_types.hpp" -#include "../../implementation/service_discovery/include/eventgroupentry_impl.hpp" -#include "../../implementation/message/include/message_impl.hpp" -#include "pending_subscription_test_globals.hpp" - -static char* remote_address; -static char* local_address; - -class pending_subscription : public ::testing::Test { -public: - pending_subscription() : - work_(std::make_shared(io_)), - io_thread_(std::bind(&pending_subscription::io_run, this)) {} -protected: - - void TearDown() { - work_.reset(); - io_thread_.join(); - io_.stop(); - } - - void io_run() { - io_.run(); - } - - boost::asio::io_service io_; - std::shared_ptr work_; - std::thread io_thread_; -}; - -/* - * @test Send 16 subscriptions to the service and check that every - * subscription is answered with an SubscribeEventgroupAck entry by the service. - * Check that the subscription is active at the end of the test and check that - * the notifications send by the service receive the client - */ -TEST_F(pending_subscription, send_multiple_subscriptions) -{ - std::promise trigger_notifications; - - boost::asio::ip::udp::socket udp_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); - udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); - - std::thread receive_thread([&](){ - bool keep_receiving(true); - std::vector receive_buffer(4096); - std::vector its_received_events; - std::uint32_t subscribe_acks_receiveid = 0; - std::uint32_t events_received = 0; - - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = udp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - ADD_FAILURE() << __func__ << " error: " << error.message(); - } else { - - std::uint32_t its_pos = 0; - - while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; - vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); - - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); - its_pos += its_message_size; - bytes_transferred -= its_message_size; - - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_EQ(2u, sd_msg.get_entries().size()); - for (const auto& e : sd_msg.get_entries()) { - EXPECT_TRUE(e->is_eventgroup_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); - EXPECT_EQ(3u, e->get_ttl()); - EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); - EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id || - its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id+1); - subscribe_acks_receiveid++; - } - } - EXPECT_EQ(0u, sd_msg.get_options().size()); - } else { // non-sd-message - vsomeip::message_impl msg; - EXPECT_TRUE(msg.deserialize(&its_deserializer)); - if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); - EXPECT_EQ(0x2222, msg.get_client()); - } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - its_received_events.push_back(msg.get_method()); - if (its_received_events.size() == 2) { - EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[0]); - EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[1]); - events_received = 2; - } - EXPECT_EQ(1u, msg.get_payload()->get_length()); - EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(0x0, msg.get_client()); - } - } - } - if (subscribe_acks_receiveid == 30) { // all subscribeAcks received - trigger_notifications.set_value(true); - subscribe_acks_receiveid++; // don't set promise value again - } - if (its_received_events.size() == 2 && events_received == 2) { - // all events received as well - keep_receiving = false; - } - } - } - }); - - std::thread send_thread([&]() { - try { - std::uint8_t its_subscribe_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x40, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, // length entries array - 0x06, 0x00, 0x00, 0x10, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x10, 0x00, // eventgroup - 0x06, 0x00, 0x00, 0x10, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x10, 0x01, // eventgroup 2 - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // ip address - 0x00, 0x11, 0x77, 0x1a - }; - boost::asio::ip::address its_local_address = - boost::asio::ip::address::from_string(std::string(local_address)); - std::memcpy(&its_subscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); - - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30490); - for (int var = 0; var < 15; ++var) { - udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); - ++its_subscribe_message[11]; - } - - - if (std::future_status::timeout == trigger_notifications.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive all SubscribeAcks within time"; - } else { - // call notify method - std::uint8_t trigger_notifications_call[] = { - 0x11, 0x22, 0x42, 0x42, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x01, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); - } - - // call shutdown method - std::uint8_t shutdown_call[] = { - 0x11, 0x22, 0x14, 0x04, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); - } catch (...) { - ASSERT_FALSE(true); - } - - }); - - send_thread.join(); - receive_thread.join(); - boost::system::error_code ec; - udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket.close(ec); -} - -/* - * @test Send 16 subscriptions to the service while alternating between Subscribe - * and Unsubscribe and check that every SubscribeEventgroupEntry (ttl > 0) - * is answered with an SubscribeEventgroupAck entry by the service. - * Check that the subscription is active at the end of the test and check that - * the notifications send by the service receive the client - */ -TEST_F(pending_subscription, send_alternating_subscribe_unsubscribe) -{ - std::promise trigger_notifications; - - boost::asio::ip::udp::socket udp_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); - udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); - - std::thread receive_thread([&](){ - const std::uint32_t expected_acks(8); - std::atomic acks_received(0); - - const std::uint32_t expected_responses(1); - std::atomic responses_received(0); - - const std::uint32_t expected_notifications(2); - std::atomic notifications_received(0); - - bool triggered_notifications(false); - - std::vector receive_buffer(4096); - std::vector its_received_events; - - bool keep_receiving(true); - - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = udp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - acks_received = expected_acks; - responses_received = expected_responses; - ADD_FAILURE() << __func__ << " error: " << error.message(); - } else { - #if 0 - std::stringstream str; - for (size_t i = 0; i < bytes_transferred; i++) { - str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; - } - std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; - #endif - std::uint32_t its_pos = 0; - - while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; - vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); - - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); - its_pos += its_message_size; - bytes_transferred -= its_message_size; - - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_EQ(2u, sd_msg.get_entries().size()); - for (const auto& e : sd_msg.get_entries()) { - EXPECT_TRUE(e->is_eventgroup_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); - EXPECT_EQ(16u, e->get_ttl()); - EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); - EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id || - its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id+1); - } - } - EXPECT_EQ(0u, sd_msg.get_options().size()); - acks_received++; - } else { // non-sd-message - vsomeip::message_impl msg; - EXPECT_TRUE(msg.deserialize(&its_deserializer)); - if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); - EXPECT_EQ(0x2222, msg.get_client()); - responses_received++; - } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - its_received_events.push_back(msg.get_method()); - if (its_received_events.size() == 2) { - EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[0]); - EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[1]); - } - EXPECT_EQ(1u, msg.get_payload()->get_length()); - EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(0x0, msg.get_client()); - notifications_received++; - } - } - - if (!triggered_notifications && acks_received == expected_acks) { // all subscribeAcks received - trigger_notifications.set_value(true); - triggered_notifications = true; - } - } - } - if (acks_received == expected_acks && - responses_received == expected_responses && - notifications_received == expected_notifications) { - keep_receiving = false; - } - } - - - EXPECT_EQ(expected_acks, acks_received); - EXPECT_EQ(expected_responses, responses_received); - EXPECT_EQ(expected_notifications, notifications_received); - }); - - std::thread send_thread([&]() { - try { - std::uint8_t its_subscribe_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x40, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, // length entries array - 0x06, 0x00, 0x00, 0x10, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL - 0x00, 0x00, 0x10, 0x00, // eventgroup - 0x06, 0x00, 0x00, 0x10, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL - 0x00, 0x00, 0x10, 0x01, // eventgroup 2 - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // ip address - 0x00, 0x11, 0x77, 0x1a - }; - - boost::asio::ip::address its_local_address = - boost::asio::ip::address::from_string(std::string(local_address)); - std::memcpy(&its_subscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); - - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30490); - for (int var = 0; var < 15; ++var) { - udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); - ++its_subscribe_message[11]; - if (its_subscribe_message[11] % 2) { - its_subscribe_message[35] = 16; - its_subscribe_message[51] = 16; - } else { - its_subscribe_message[35] = 0; - its_subscribe_message[51] = 0; - } - } - - if (std::future_status::timeout == trigger_notifications.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive all SubscribeAcks within time"; - } else { - // call notify method - std::uint8_t trigger_notifications_call[] = { - 0x11, 0x22, 0x42, 0x42, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x01, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); - } - - // call shutdown method - std::uint8_t shutdown_call[] = { - 0x11, 0x22, 0x14, 0x04, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); - } catch (...) { - ASSERT_FALSE(true); - } - - }); - - send_thread.join(); - receive_thread.join(); - boost::system::error_code ec; - udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket.close(ec); -} - -/* - * @test Send 16 subscriptions to the service while only two contain a - * SubscribeEventgroupEntry and the rest contain StopSubscribeEventgroupEntries - * and check that all subscriptions with SubscribeEventgroupEntries are - * answered with an SubscribeEventgroupAck entry by the service. - * Check that the subscription is active at the end of the test and check that - * the notifications send by the service receive the client - */ -TEST_F(pending_subscription, send_multiple_unsubscriptions) -{ - std::promise trigger_notifications; - - boost::asio::ip::udp::socket udp_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); - udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); - - std::thread receive_thread([&](){ - const std::uint32_t expected_acks(2); - std::atomic acks_received(0); - - const std::uint32_t expected_responses(1); - std::atomic responses_received(0); - - const std::uint32_t expected_notifications(2); - std::atomic notifications_received(0); - - bool triggered_notifications(false); - - std::vector receive_buffer(4096); - std::vector its_received_events; - - bool keep_receiving(true); - - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = udp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - acks_received = expected_acks; - responses_received = expected_responses; - ADD_FAILURE() << __func__ << " error: " << error.message(); - } else { - #if 0 - std::stringstream str; - for (size_t i = 0; i < bytes_transferred; i++) { - str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; - } - std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; - #endif - std::uint32_t its_pos = 0; - while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; - vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); - its_pos += its_message_size; - bytes_transferred -= its_message_size; - - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_EQ(2u, sd_msg.get_entries().size()); - for (const auto& e : sd_msg.get_entries()) { - EXPECT_TRUE(e->is_eventgroup_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); - EXPECT_EQ(16u, e->get_ttl()); - EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); - EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id || - its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id+1); - } - } - EXPECT_EQ(0u, sd_msg.get_options().size()); - acks_received++; - } else { // non-sd-message - vsomeip::message_impl msg; - EXPECT_TRUE(msg.deserialize(&its_deserializer)); - if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); - EXPECT_EQ(0x2222, msg.get_client()); - responses_received++; - } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - its_received_events.push_back(msg.get_method()); - if (its_received_events.size() == 2) { - EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[0]); - EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[1]); - } - EXPECT_EQ(1u, msg.get_payload()->get_length()); - EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(0x0, msg.get_client()); - notifications_received++; - } - } - } - if (!triggered_notifications && acks_received == expected_acks) { // all subscribeAcks received - trigger_notifications.set_value(true); - triggered_notifications = true; - } - } - if (acks_received == expected_acks && - responses_received == expected_responses && - notifications_received == expected_notifications) { - std::cerr << "every thing received" << std::endl; - keep_receiving = false; - } - } - - EXPECT_EQ(expected_acks, acks_received); - EXPECT_EQ(expected_responses, responses_received); - EXPECT_EQ(expected_notifications, notifications_received); - }); - - std::thread send_thread([&]() { - try { - std::uint8_t its_subscribe_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x40, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, // length entries array - 0x06, 0x00, 0x00, 0x10, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL - 0x00, 0x00, 0x10, 0x00, // eventgroup - 0x06, 0x00, 0x00, 0x10, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL - 0x00, 0x00, 0x10, 0x01, // eventgroup 2 - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // ip address - 0x00, 0x11, 0x77, 0x1a - }; - - boost::asio::ip::address its_local_address = - boost::asio::ip::address::from_string(std::string(local_address)); - std::memcpy(&its_subscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); - - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30490); - for (int var = 0; var < 15; ++var) { - if (its_subscribe_message[11] == 15 || its_subscribe_message[11] == 0x1) { - its_subscribe_message[35] = 16; - its_subscribe_message[51] = 16; - } else { - its_subscribe_message[35] = 0; - its_subscribe_message[51] = 0; - } - udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); - ++its_subscribe_message[11]; - } - - if (std::future_status::timeout == trigger_notifications.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive all SubscribeAcks within time"; - } else { - // call notify method - std::uint8_t trigger_notifications_call[] = { - 0x11, 0x22, 0x42, 0x42, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x01, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); - } - - // call shutdown method - std::uint8_t shutdown_call[] = { - 0x11, 0x22, 0x14, 0x04, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); - } catch (...) { - ASSERT_FALSE(true); - } - - }); - - send_thread.join(); - receive_thread.join(); - boost::system::error_code ec; - udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket.close(ec); -} - -/* - * @test Send 16 subscriptions to the service and check that every second - * subscription is answered with an SubscribeEventgroupNack entry by the service. - * Check that the subscription is active at the end of the test and check that - * the notifications send by the service receive the client - */ -TEST_F(pending_subscription, send_alternating_subscribe_nack_unsubscribe) -{ - std::promise trigger_notifications; - - boost::asio::ip::udp::socket udp_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); - udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); - - std::thread receive_thread([&](){ - const std::uint32_t expected_acks(8); - std::atomic acks_received(0); - - const std::uint32_t expected_nacks(8); - std::atomic nacks_received(0); - - const std::uint32_t expected_responses(1); - std::atomic responses_received(0); - - const std::uint32_t expected_notifications(2); - std::atomic notifications_received(0); - - bool triggered_notifications(false); - bool keep_receiving(true); - - std::vector receive_buffer(4096); - std::vector its_received_events; - - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = udp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - acks_received = expected_acks; - responses_received = expected_responses; - nacks_received = expected_nacks; - ADD_FAILURE() << __func__ << " error: " << error.message(); - } else { - #if 0 - std::stringstream str; - for (size_t i = 0; i < bytes_transferred; i++) { - str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; - } - std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; - #endif - std::uint32_t its_pos = 0; - while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; - vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); - - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); - its_pos += its_message_size; - bytes_transferred -= its_message_size; - - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_EQ(2u, sd_msg.get_entries().size()); - for (const auto& e : sd_msg.get_entries()) { - EXPECT_TRUE(e->is_eventgroup_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); - if (e->get_ttl()) { - EXPECT_EQ(16u, e->get_ttl()); - acks_received++; - } else { - EXPECT_EQ(0u, e->get_ttl()); - nacks_received++; - } - EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); - EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id || - its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id+1); - } - } - EXPECT_EQ(0u, sd_msg.get_options().size()); - } else { // non-sd-message - vsomeip::message_impl msg; - EXPECT_TRUE(msg.deserialize(&its_deserializer)); - if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); - EXPECT_EQ(0x2222, msg.get_client()); - responses_received++; - } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - its_received_events.push_back(msg.get_method()); - if (its_received_events.size() == 2) { - EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[0]); - EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[1]); - } - EXPECT_EQ(1u, msg.get_payload()->get_length()); - EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(0x0, msg.get_client()); - notifications_received++; - } - } - - - if (!triggered_notifications && acks_received == expected_acks && - nacks_received == expected_nacks) { // all subscribeAcks received - trigger_notifications.set_value(true); - triggered_notifications = true; - } - } - } - if (nacks_received == expected_nacks && - acks_received == expected_acks && - notifications_received == expected_notifications && - responses_received == expected_responses) { - keep_receiving = false; - } - } - - EXPECT_EQ(expected_acks, acks_received); - EXPECT_EQ(expected_nacks, nacks_received); - EXPECT_EQ(expected_responses, responses_received); - EXPECT_EQ(expected_notifications, notifications_received); - }); - - std::thread send_thread([&]() { - try { - std::uint8_t its_subscribe_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x40, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, // length entries array - 0x06, 0x00, 0x00, 0x10, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL - 0x00, 0x00, 0x10, 0x00, // eventgroup - 0x06, 0x00, 0x00, 0x10, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL - 0x00, 0x00, 0x10, 0x01, // eventgroup 2 - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // ip address - 0x00, 0x11, 0x77, 0x1a - }; - - boost::asio::ip::address its_local_address = - boost::asio::ip::address::from_string(std::string(local_address)); - std::memcpy(&its_subscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); - - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30490); - for (int var = 0; var < 15; ++var) { - udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); - ++its_subscribe_message[11]; - if (its_subscribe_message[11] % 2) { - its_subscribe_message[35] = 16; - its_subscribe_message[51] = 16; - } else { - its_subscribe_message[35] = 0; - its_subscribe_message[51] = 0; - } - } - - if (std::future_status::timeout == trigger_notifications.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive all SubscribeAcks within time"; - } else { - // call notify method - std::uint8_t trigger_notifications_call[] = { - 0x11, 0x22, 0x42, 0x42, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x01, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); - } - - // call shutdown method - std::uint8_t shutdown_call[] = { - 0x11, 0x22, 0x14, 0x04, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); - } catch (...) { - ASSERT_FALSE(true); - } - - }); - - send_thread.join(); - receive_thread.join(); - boost::system::error_code ec; - udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket.close(ec); -} - -/* - * @test Send 16 subscriptions containing an UDP and TCP endpoint option - * to the service while alternating between Subscribe - * and Unsubscribe and check that every SubscribeEventgroupEntry (ttl > 0) - * is answered with an SubscribeEventgroupAck entry by the service. - * Check that the subscription is active at the end of the test and check that - * the notifications send by the service receive the client - */ -TEST_F(pending_subscription, send_alternating_subscribe_unsubscribe_same_port) -{ - std::promise trigger_notifications; - std::promise tcp_connected; - boost::asio::ip::udp::socket udp_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); - udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); - boost::asio::ip::tcp::socket tcp_socket(io_, - boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 30490)); - tcp_socket.set_option(boost::asio::socket_base::reuse_address(true)); - tcp_socket.set_option(boost::asio::socket_base::linger(true, 0)); - - std::thread receive_thread([&](){ - const std::uint32_t expected_acks(8); - std::atomic acks_received(0); - - const std::uint32_t expected_responses(1); - std::atomic responses_received(0); - - const std::uint32_t expected_notifications(2); - std::atomic notifications_received(0); - - bool triggered_notifications(false); - - std::vector receive_buffer(4096); - std::vector its_received_events; - - boost::system::error_code ec; - tcp_socket.connect(boost::asio::ip::tcp::endpoint( - boost::asio::ip::address::from_string(remote_address), 40001), ec); - ASSERT_EQ(0, ec.value()); - tcp_connected.set_value(); - - bool keep_receiving(true); - - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = udp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - acks_received = expected_acks; - responses_received = expected_responses; - ADD_FAILURE() << __func__ << " error: " << error.message(); - } else { - - std::uint32_t its_pos = 0; - - while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; - vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); - - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); - its_pos += its_message_size; - bytes_transferred -= its_message_size; - - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_EQ(2u, sd_msg.get_entries().size()); - for (const auto& e : sd_msg.get_entries()) { - EXPECT_TRUE(e->is_eventgroup_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); - EXPECT_EQ(16u, e->get_ttl()); - EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); - EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id || - its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id+1); - } - } - EXPECT_EQ(0u, sd_msg.get_options().size()); - acks_received++; - } else { // non-sd-message - vsomeip::message_impl msg; - EXPECT_TRUE(msg.deserialize(&its_deserializer)); - if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); - EXPECT_EQ(0x2222, msg.get_client()); - responses_received++; - } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - its_received_events.push_back(msg.get_method()); - if (its_received_events.size() == 2) { - EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[0]); - EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[1]); - } - EXPECT_EQ(1u, msg.get_payload()->get_length()); - EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(0x0, msg.get_client()); - notifications_received++; - } - } - - - if (!triggered_notifications && acks_received == expected_acks) { // all subscribeAcks received - trigger_notifications.set_value(true); - triggered_notifications = true; - } - } - } - if (acks_received == expected_acks && - responses_received == expected_responses && - notifications_received == expected_notifications) { - keep_receiving = false; - } - } - - - EXPECT_EQ(expected_acks, acks_received); - EXPECT_EQ(expected_responses, responses_received); - EXPECT_EQ(expected_notifications, notifications_received); - }); - - std::thread send_thread([&]() { - if (std::future_status::timeout == tcp_connected.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't establish tcp connection within time"; - } - - try { - std::uint8_t its_subscribe_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x4C, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, // length entries array - 0x06, 0x00, 0x00, 0x20, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL - 0x00, 0x00, 0x10, 0x00, // eventgroup - 0x06, 0x00, 0x00, 0x20, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL - 0x00, 0x00, 0x10, 0x01, // eventgroup 2 - 0x00, 0x00, 0x00, 0x18, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // ip address - 0x00, 0x11, 0x77, 0x1a, - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // ip address - 0x00, 0x06, 0x77, 0x1a - }; - - boost::asio::ip::address its_local_address = - boost::asio::ip::address::from_string(std::string(local_address)); - std::memcpy(&its_subscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); - std::memcpy(&its_subscribe_message[76], &its_local_address.to_v4().to_bytes()[0], 4); - - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30490); - for (int var = 0; var < 15; ++var) { - udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); - ++its_subscribe_message[11]; - if (its_subscribe_message[11] % 2) { - its_subscribe_message[35] = 16; - its_subscribe_message[51] = 16; - } else { - its_subscribe_message[35] = 0; - its_subscribe_message[51] = 0; - } - } - - if (std::future_status::timeout == trigger_notifications.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive all SubscribeAcks within time"; - } else { - // call notify method - std::uint8_t trigger_notifications_call[] = { - 0x11, 0x22, 0x42, 0x42, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x01, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); - } - - // call shutdown method - std::uint8_t shutdown_call[] = { - 0x11, 0x22, 0x14, 0x04, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); - } catch (...) { - ASSERT_FALSE(true); - } - - }); - - send_thread.join(); - receive_thread.join(); - boost::system::error_code ec; - tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket.close(ec); - udp_socket.close(ec); -} - -/* - * @test Send a subscription as single message and afterwards send a - * resubscription containing a new subscription in the same message and check - * to receive initial event - */ -TEST_F(pending_subscription, subscribe_resubscribe_mixed) -{ - std::promise first_initial_event_received; - std::promise second_initial_event_received; - - boost::asio::ip::udp::socket udp_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); - udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); - - std::thread receive_thread([&](){ - std::vector receive_buffer(4096); - std::vector its_received_events; - - const std::uint32_t expected_acks(3); - std::atomic acks_received(0); - - const std::uint32_t expected_responses(1); - std::atomic responses_received(0); - - const std::uint32_t expected_notifications(2); - std::atomic notifications_received(0); - - bool keep_receiving(true); - bool first_initial_event_checked(false); - bool second_initial_event_checked(false); - - - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transfered = udp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - ADD_FAILURE() << __func__ << " error: " << error.message(); - } else { - - std::uint32_t its_pos = 0; - - while (bytes_transfered > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; - vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); - - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); - its_pos += its_message_size; - bytes_transfered -= its_message_size; - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_GE(2u, sd_msg.get_entries().size()); - for (const auto& e : sd_msg.get_entries()) { - EXPECT_TRUE(e->is_eventgroup_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); - EXPECT_EQ(3u, e->get_ttl()); - EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); - EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { - acks_received++; - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id || - its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id+1); - } - } - EXPECT_EQ(0u, sd_msg.get_options().size()); - } else { // non-sd-message - vsomeip::message_impl msg; - EXPECT_TRUE(msg.deserialize(&its_deserializer)); - if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); - EXPECT_EQ(0x2222, msg.get_client()); - responses_received++; - } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - its_received_events.push_back(msg.get_method()); - if (its_received_events.size() == 2) { - EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[0]); - EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[1]); - } - EXPECT_EQ(1u, msg.get_payload()->get_length()); - EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(0x0, msg.get_client()); - notifications_received++; - } - } - - if (!first_initial_event_checked && notifications_received == 1) { - EXPECT_EQ(1u, its_received_events.size()); - EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[0]); - // all subscribeAcks and one initial event of first event received - first_initial_event_received.set_value(); - first_initial_event_checked = true; - } - - if (!second_initial_event_checked && notifications_received == 2) { // events were received as well - // all subscribeAcks and one initial event of second event received - EXPECT_EQ(2u, its_received_events.size()); - EXPECT_EQ(static_cast(pending_subscription_test::service.event_id + 1u), its_received_events[0]); - EXPECT_EQ(pending_subscription_test::service.event_id, its_received_events[1]); - second_initial_event_received.set_value(); - second_initial_event_checked = true; - } - if (notifications_received == 2 && responses_received == 1) { - keep_receiving = false; - } - } - } - } - EXPECT_EQ(expected_acks, acks_received); - EXPECT_EQ(expected_notifications, notifications_received); - EXPECT_EQ(expected_responses, responses_received); - }); - - std::thread send_thread([&]() { - try { - // call notify method to ensure to receive initial events - std::uint8_t trigger_notifications_call[] = { - 0x11, 0x22, 0x42, 0x42, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x01, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); - - std::uint8_t its_subscribe_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x30, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, // length entries array - 0x06, 0x00, 0x00, 0x10, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x10, 0x01, // eventgroup - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // ip address - 0x00, 0x11, 0x77, 0x1a - }; - boost::asio::ip::address its_local_address = - boost::asio::ip::address::from_string(std::string(local_address)); - std::memcpy(&its_subscribe_message[48], &its_local_address.to_v4().to_bytes()[0], 4); - - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30490); - - udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); - - - - if (std::future_status::timeout == first_initial_event_received.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive all SubscribeAck of first subscription within time"; - } - - // send second subscription with resubscription and new subscription - std::uint8_t its_subscribe_resubscribe_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x40, // length - 0x00, 0x00, 0x00, 0x02, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, // length entries array - 0x06, 0x00, 0x00, 0x10, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x10, 0x00, // eventgroup - 0x06, 0x00, 0x00, 0x10, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x10, 0x01, // eventgroup 2 - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // ip address - 0x00, 0x11, 0x77, 0x1a - }; - std::memcpy(&its_subscribe_resubscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); - udp_socket.send_to(boost::asio::buffer(its_subscribe_resubscribe_message), target_sd); - - if (std::future_status::timeout == second_initial_event_received.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive all SubscribeAck of second subscription within time"; - } - // call shutdown method - std::uint8_t shutdown_call[] = { - 0x11, 0x22, 0x14, 0x04, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); - } catch (...) { - ASSERT_FALSE(true); - } - - }); - - send_thread.join(); - receive_thread.join(); - boost::system::error_code ec; - udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket.close(ec); -} - -/* - * @test Send a SD message containing a Subscription followed by a StopSubscribe - * Subscribe entry to the same service. Check to receive an initial event - */ -TEST_F(pending_subscription, send_subscribe_stop_subscribe_subscribe) -{ - std::promise trigger_notifications; - std::promise tcp_connected; - boost::asio::ip::udp::socket udp_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); - udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); - boost::asio::ip::tcp::socket tcp_socket(io_, - boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 30490)); - tcp_socket.set_option(boost::asio::socket_base::reuse_address(true)); - tcp_socket.set_option(boost::asio::socket_base::linger(true, 0)); - - std::thread receive_thread([&](){ - const std::uint32_t expected_acks(2); - std::atomic acks_received(0); - - const std::uint32_t expected_responses(1); - std::atomic responses_received(0); - - const std::uint32_t expected_notifications(1); - std::atomic notifications_received(0); - - bool triggered_notifications(false); - - std::vector receive_buffer(4096); - std::vector its_received_events; - - boost::system::error_code ec; - tcp_socket.connect(boost::asio::ip::tcp::endpoint( - boost::asio::ip::address::from_string(remote_address), 40001), ec); - ASSERT_EQ(0, ec.value()); - tcp_connected.set_value(); - - bool keep_receiving(true); - - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = udp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - acks_received = expected_acks; - responses_received = expected_responses; - ADD_FAILURE() << __func__ << " error: " << error.message(); - } else { - - std::uint32_t its_pos = 0; - - while (bytes_transferred > 0) { - #if 0 - std::stringstream str; - for (size_t i = 0; i < bytes_transferred; i++) { - str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; - } - std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; - #endif - - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; - vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); - - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); - its_pos += its_message_size; - bytes_transferred -= its_message_size; - - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_EQ(1u, sd_msg.get_entries().size()); - for (const auto& e : sd_msg.get_entries()) { - EXPECT_TRUE(e->is_eventgroup_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK, e->get_type()); - EXPECT_EQ(16u, e->get_ttl()); - EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); - EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_TRUE(its_casted_entry->get_eventgroup() == pending_subscription_test::service.eventgroup_id); - } - } - EXPECT_EQ(0u, sd_msg.get_options().size()); - acks_received++; - } else { // non-sd-message - vsomeip::message_impl msg; - EXPECT_TRUE(msg.deserialize(&its_deserializer)); - if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); - EXPECT_EQ(0x2222, msg.get_client()); - responses_received++; - } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - its_received_events.push_back(msg.get_method()); - EXPECT_EQ(1u, its_received_events.size()); - EXPECT_EQ(1u, msg.get_payload()->get_length()); - EXPECT_EQ(0xDD, *msg.get_payload()->get_data()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(0x0, msg.get_client()); - notifications_received++; - } - } - - if (!triggered_notifications && acks_received == expected_acks) { // all subscribeAcks received - trigger_notifications.set_value(true); - triggered_notifications = true; - } - } - if (acks_received == expected_acks && - responses_received == expected_responses && - notifications_received == expected_notifications) { - keep_receiving = false; - } - } - } - EXPECT_EQ(expected_acks, acks_received); - EXPECT_EQ(expected_responses, responses_received); - EXPECT_EQ(expected_notifications, notifications_received); - }); - - std::thread send_thread([&]() { - if (std::future_status::timeout == tcp_connected.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't establish tcp connection within time"; - } - - try { - std::uint8_t its_normal_subscribe_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x30, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, // length entries array - 0x06, 0x00, 0x00, 0x10, // subscribe Eventgroup entry - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL - 0x00, 0x00, 0x10, 0x00, // eventgroup - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // ip address - 0x00, 0x11, 0x77, 0x1a - }; - std::uint8_t its_subscribe_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x50, // length - 0x00, 0x00, 0x00, 0x02, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x30, // length entries array - 0x06, 0x00, 0x00, 0x10, // subscribe Eventgroup entry - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x10, // 16 seconds TTL - 0x00, 0x00, 0x10, 0x00, // eventgroup - 0x06, 0x00, 0x00, 0x10, // Stop subscribe Eventgroup entry - 0x11, 0x22, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x10, 0x00, - 0x06, 0x00, 0x00, 0x10, // subscribe Eventgroup entry - 0x11, 0x22, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x10, - 0x00, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // ip address - 0x00, 0x11, 0x77, 0x1a - }; - - boost::asio::ip::address its_local_address = - boost::asio::ip::address::from_string(std::string(local_address)); - std::memcpy(&its_subscribe_message[80], &its_local_address.to_v4().to_bytes()[0], 4); - std::memcpy(&its_normal_subscribe_message[48], &its_local_address.to_v4().to_bytes()[0], 4); - - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30490); - - udp_socket.send_to(boost::asio::buffer(its_normal_subscribe_message), target_sd); - udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); - - if (std::future_status::timeout == trigger_notifications.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive all SubscribeAcks within time"; - } else { - // call notify method - std::uint8_t trigger_notifications_call[] = { - 0x11, 0x22, 0x42, 0x42, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x01, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); - } - - // call shutdown method - std::uint8_t shutdown_call[] = { - 0x11, 0x22, 0x14, 0x04, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); - } catch (...) { - ASSERT_FALSE(true); - } - - }); - send_thread.join(); - receive_thread.join(); - boost::system::error_code ec; - tcp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - tcp_socket.close(ec); - udp_socket.close(ec); -} - -/* - * @test Send a message with message type 0x0 (REQUEST) to the remote SD port - * and check if the remote SD continues to send offers - */ -TEST_F(pending_subscription, send_request_to_sd_port) -{ - std::promise all_offers_received; - - boost::asio::ip::udp::socket udp_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - udp_socket.set_option(boost::asio::ip::multicast::enable_loopback(false)); - udp_socket.set_option(boost::asio::ip::multicast::join_group( - boost::asio::ip::address::from_string("224.0.23.1").to_v4())); - udp_socket.set_option(boost::asio::socket_base::reuse_address(true)); - udp_socket.set_option(boost::asio::socket_base::linger(true, 0)); - - std::thread receive_thread([&](){ - bool keep_receiving(true); - std::vector receive_buffer(4096); - std::vector its_received_events; - - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = udp_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - ADD_FAILURE() << __func__ << " error: " << error.message(); - } else { - std::uint32_t its_pos = 0; - while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; - vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); - - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); - its_pos += its_message_size; - bytes_transferred -= its_message_size; - - #if 0 - std::stringstream str; - for (size_t i = 0; i < bytes_transferred; i++) { - str << std::hex << std::setw(2) << std::setfill('0') << std::uint32_t(receive_buffer[i]) << " "; - } - std::cout << __func__ << " received: " << std::dec << bytes_transferred << " bytes: " << str.str() << std::endl; - #endif - static int offers_received = 0; - static int responses_received = 0; - - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_EQ(1u, sd_msg.get_entries().size()); - EXPECT_EQ(2u, sd_msg.get_options().size()); - for (const auto& e : sd_msg.get_entries()) { - EXPECT_TRUE(e->is_service_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); - EXPECT_EQ(0xffffffu, e->get_ttl()); - EXPECT_EQ(pending_subscription_test::service.service_id, e->get_service()); - EXPECT_EQ(pending_subscription_test::service.instance_id, e->get_instance()); - offers_received++; - } - } else { // non-sd-message - vsomeip::message_impl msg; - EXPECT_TRUE(msg.deserialize(&its_deserializer)); - if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); - EXPECT_EQ(pending_subscription_test::service.service_id, msg.get_service()); - EXPECT_EQ(pending_subscription_test::service.shutdown_method_id, msg.get_method()); - EXPECT_EQ(0x2222, msg.get_client()); - responses_received++; - } - } - - if (responses_received == 1) { // response to shutdown method was received as well - keep_receiving = false; - } else if (offers_received == 3 ) { // all multiple offers received - try { - all_offers_received.set_value(true); - } catch (const std::future_error& e) { - - } - } - } - } - } - }); - - std::thread send_thread([&]() { - try { - std::uint8_t its_subscribe_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x40, // length - 0x00, 0x00, 0x10, 0x01, - 0x01, 0x01, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, // message type is set to 0x0 (REQUEST) - 0x00, 0x00, 0x00, 0x20, // length entries array - 0x06, 0x00, 0x00, 0x10, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x10, 0x00, // eventgroup - 0x06, 0x00, 0x00, 0x10, - 0x11, 0x22, 0x00, 0x01, // service / instance - 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x10, 0x01, // eventgroup 2 - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // ip address - 0x00, 0x11, 0x77, 0x1a - }; - boost::asio::ip::address its_local_address = - boost::asio::ip::address::from_string(std::string(local_address)); - std::memcpy(&its_subscribe_message[64], &its_local_address.to_v4().to_bytes()[0], 4); - - boost::asio::ip::udp::socket::endpoint_type target_sd( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30490); - for (int var = 0; var < 15; ++var) { - udp_socket.send_to(boost::asio::buffer(its_subscribe_message), target_sd); - ++its_subscribe_message[11]; - } - - - if (std::future_status::timeout == all_offers_received.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive all Offers within time"; - } - - { - // call notify method (but don't expect notifications) to allow - // service to exit - std::uint8_t trigger_notifications_call[] = { - 0x11, 0x22, 0x42, 0x42, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x01, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(trigger_notifications_call), target_service); - } - - { - // call shutdown method - std::uint8_t shutdown_call[] = { - 0x11, 0x22, 0x14, 0x04, - 0x00, 0x00, 0x00, 0x08, - 0x22, 0x22, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service( - boost::asio::ip::address::from_string(std::string(remote_address)), - 30001); - udp_socket.send_to(boost::asio::buffer(shutdown_call), target_service); - } - - } catch (...) { - ASSERT_FALSE(true); - } - - }); - - send_thread.join(); - receive_thread.join(); - boost::system::error_code ec; - udp_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket.close(ec); -} - -#ifndef _WIN32 -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - if(argc < 4) { - std::cerr << "Please pass an target and local IP address and test mode to this binary like: " - << argv[0] << " 10.0.3.1 10.0.3.202 SUBSCRIBE" << std::endl; - std::cerr << "Testmodes are [SUBSCRIBE, SUBSCRIBE_UNSUBSCRIBE, UNSUBSCRIBE]" << std::endl; - exit(1); - } - remote_address = argv[1]; - local_address = argv[2]; - std::string its_testmode = argv[3]; - if (its_testmode == std::string("SUBSCRIBE")) { - ::testing::GTEST_FLAG(filter) = "*send_multiple_subscriptions"; - } else if (its_testmode == std::string("SUBSCRIBE_UNSUBSCRIBE")) { - ::testing::GTEST_FLAG(filter) = "*send_alternating_subscribe_unsubscribe"; - } else if (its_testmode == std::string("UNSUBSCRIBE")) { - ::testing::GTEST_FLAG(filter) = "*send_multiple_unsubscriptions"; - } else if (its_testmode == std::string("SUBSCRIBE_UNSUBSCRIBE_NACK")) { - ::testing::GTEST_FLAG(filter) = "*send_alternating_subscribe_nack_unsubscribe"; - } else if (its_testmode == std::string("SUBSCRIBE_UNSUBSCRIBE_SAME_PORT")) { - ::testing::GTEST_FLAG(filter) = "*send_alternating_subscribe_unsubscribe_same_port"; - } else if (its_testmode == std::string("SUBSCRIBE_RESUBSCRIBE_MIXED")) { - ::testing::GTEST_FLAG(filter) = "*subscribe_resubscribe_mixed"; - } else if (its_testmode == std::string("SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE")) { - ::testing::GTEST_FLAG(filter) = "*send_subscribe_stop_subscribe_subscribe"; - } else if (its_testmode == std::string("REQUEST_TO_SD")) { - ::testing::GTEST_FLAG(filter) = "*send_request_to_sd_port"; - } - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/pending_subscription_tests/pending_subscription_test_service.cpp b/test/pending_subscription_tests/pending_subscription_test_service.cpp deleted file mode 100644 index d68686c..0000000 --- a/test/pending_subscription_tests/pending_subscription_test_service.cpp +++ /dev/null @@ -1,389 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "pending_subscription_test_globals.hpp" - -class pending_subscription_test_service { -public: - pending_subscription_test_service(struct pending_subscription_test::service_info _service_info, pending_subscription_test::test_mode_e _testmode) : - service_info_(_service_info), - testmode_(_testmode), - app_(vsomeip::runtime::get()->create_application("pending_subscription_test_service")), - wait_until_registered_(true), - wait_until_shutdown_method_called_(true), - subscription_accepted_asynchronous_(false), - subscription_accepted_synchronous_(false), - offer_thread_(std::bind(&pending_subscription_test_service::run, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&pending_subscription_test_service::on_state, this, - std::placeholders::_1)); - - // offer field - std::set its_eventgroups; - its_eventgroups.insert(_service_info.eventgroup_id); - app_->offer_event(service_info_.service_id, 0x1, - service_info_.event_id, - its_eventgroups, vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); - - its_eventgroups.clear(); - its_eventgroups.insert(static_cast(_service_info.eventgroup_id+1u)); - - app_->offer_event(service_info_.service_id, 0x1, - static_cast(service_info_.event_id+1u), - its_eventgroups, vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, service_info_.shutdown_method_id, - std::bind(&pending_subscription_test_service::on_shutdown_method_called, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, service_info_.notify_method_id, - std::bind(&pending_subscription_test_service::on_notify_method_called, this, - std::placeholders::_1)); - - app_->register_async_subscription_handler(service_info_.service_id, - 0x1, service_info_.eventgroup_id, - std::bind(&pending_subscription_test_service::subscription_handler_async, - this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, - std::placeholders::_4, std::placeholders::_5)); - app_->register_subscription_handler(service_info_.service_id, - 0x1, static_cast(service_info_.eventgroup_id+1u), - std::bind(&pending_subscription_test_service::subscription_handler, - this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, - std::placeholders::_4)); - app_->start(); - } - - ~pending_subscription_test_service() { - offer_thread_.join(); - } - - void offer() { - app_->offer_service(service_info_.service_id, 0x1); - } - - void stop() { - app_->stop_offer_service(service_info_.service_id, 0x1); - app_->clear_all_handler(); - app_->stop(); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_shutdown_method_called(const std::shared_ptr &_message) { - app_->send(vsomeip::runtime::get()->create_response(_message)); - VSOMEIP_WARNING << "************************************************************"; - VSOMEIP_WARNING << "Shutdown method called -> going down!"; - VSOMEIP_WARNING << "************************************************************"; - std::lock_guard its_lock(mutex_); - wait_until_shutdown_method_called_ = false; - condition_.notify_one(); - } - - void on_notify_method_called(const std::shared_ptr &_message) { - (void)_message; - std::shared_ptr its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data( {0xDD}); - app_->notify(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_payload); - app_->notify(service_info_.service_id, service_info_.instance_id, - static_cast(service_info_.event_id + 1u) , its_payload); - notify_method_called_.set_value(true); - } - - void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - - if (testmode_ == pending_subscription_test::test_mode_e::REQUEST_TO_SD) { - // this testcase won't send valid subscriptions -> ensure to exit - subscription_accepted_asynchronous_ = true; - subscription_accepted_synchronous_ = true; - } - - while (!subscription_accepted_asynchronous_ || !subscription_accepted_synchronous_) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - switch (testmode_) { - case pending_subscription_test::test_mode_e::SUBSCRIBE: - async_subscription_handler_(true); - break; - case pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE: - case pending_subscription_test::test_mode_e::UNSUBSCRIBE: - case pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_NACK: - case pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_SAME_PORT: - case pending_subscription_test::test_mode_e::SUBSCRIBE_RESUBSCRIBE_MIXED: - case pending_subscription_test::test_mode_e::SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE: - case pending_subscription_test::test_mode_e::REQUEST_TO_SD: - default: - break; - } - - std::future itsFuture = notify_method_called_.get_future(); - if (std::future_status::timeout == itsFuture.wait_for(std::chrono::seconds(30))) { - ADD_FAILURE() << "notify method wasn't called within time!"; - } else { - EXPECT_TRUE(itsFuture.get()); - } - while (wait_until_shutdown_method_called_) { - condition_.wait(its_lock); - } - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); - stop(); - } - - void subscription_handler_async(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, - bool _subscribed, const std::function& _cbk) { - (void)_uid; - (void)_gid; - VSOMEIP_WARNING << __func__ << " " << std::hex << _client << " subscribed." << _subscribed; - if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE) { - async_subscription_handler_ = _cbk; - static int was_called = 0; - was_called++; - EXPECT_EQ(1, was_called); - EXPECT_TRUE(_subscribed); - subscription_accepted_asynchronous_ = true; - } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE) { - static int count_subscribe = 0; - static int count_unsubscribe = 0; - _subscribed ? count_subscribe++ : count_unsubscribe++; - if (count_subscribe == 1) { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - _cbk(true); - if (count_subscribe == 8 || count_unsubscribe == 7) { - subscription_accepted_asynchronous_ = true; - } - } else if (testmode_ == pending_subscription_test::test_mode_e::UNSUBSCRIBE) { - static int count_subscribe = 0; - static int count_unsubscribe = 0; - _subscribed ? count_subscribe++ : count_unsubscribe++; - if (count_subscribe == 1) { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - _cbk(true); - if (count_subscribe == 2 || count_unsubscribe == 1) { - subscription_accepted_asynchronous_ = true; - } - } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_NACK) { - static int count_subscribe = 0; - static int count_unsubscribe = 0; - _subscribed ? count_subscribe++ : count_unsubscribe++; - if (count_subscribe == 1) { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - if (_subscribed) { - _cbk(((count_subscribe + 1) % 2)); // nack every second subscription - } else { - _cbk(true); - } - if (count_subscribe == 8 || count_unsubscribe == 7) { - subscription_accepted_asynchronous_ = true; - } - } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_SAME_PORT) { - static int count_subscribe = 0; - static int count_unsubscribe = 0; - _subscribed ? count_subscribe++ : count_unsubscribe++; - if (count_subscribe == 1) { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - _cbk(true); - if (count_subscribe == 8 || count_unsubscribe == 7) { - subscription_accepted_asynchronous_ = true; - } - } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_RESUBSCRIBE_MIXED) { - static int was_called = 0; - was_called++; - EXPECT_EQ(1, was_called); - EXPECT_TRUE(_subscribed); - _cbk(true); - subscription_accepted_asynchronous_ = true; - } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE) { - static int was_called = 0; - was_called++; - EXPECT_EQ(1, was_called); - EXPECT_TRUE(_subscribed); - subscription_accepted_asynchronous_ = true; - // this test doesn't subscribe to the second eventgroup which is handled by the asynchronous - // subscription handler, set it to true here: - subscription_accepted_synchronous_ = true; - _cbk(true); - } - } - - bool subscription_handler(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) { - (void)_subscribed; - (void)_uid; - (void)_gid; - bool ret(false); - VSOMEIP_WARNING << __func__ << " " << std::hex << _client << " subscribed. " << _subscribed; - if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE) { - static int was_called = 0; - was_called++; - EXPECT_EQ(1, was_called); - EXPECT_TRUE(_subscribed); - subscription_accepted_synchronous_ = true; - ret = true; - } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE) { - static int count_subscribed = 0; - static int count_unsubscribe = 0; - _subscribed ? count_subscribed++ : count_unsubscribe++; - if (count_subscribed == 1) { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - if (count_subscribed == 8 && count_unsubscribe == 7) { - subscription_accepted_synchronous_ = true; - } - ret = true; - } else if (testmode_ == pending_subscription_test::test_mode_e::UNSUBSCRIBE) { - static int count_subscribed = 0; - static int count_unsubscribe = 0; - _subscribed ? count_subscribed++ : count_unsubscribe++; - if (count_subscribed == 1) { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - if (count_subscribed == 2 && count_unsubscribe == 1) { - subscription_accepted_synchronous_ = true; - } - ret = true; - } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_NACK) { - static int count_subscribed = 0; - static int count_unsubscribe = 0; - _subscribed ? count_subscribed++ : count_unsubscribe++; - if (count_subscribed == 1) { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - if (count_subscribed == 8 && count_unsubscribe == 7) { - subscription_accepted_synchronous_ = true; - } - if (_subscribed) { - ret = ((count_subscribed + 1) % 2); // nack every second subscription - } else { - ret = true; - } - } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_SAME_PORT) { - static int count_subscribed = 0; - static int count_unsubscribe = 0; - _subscribed ? count_subscribed++ : count_unsubscribe++; - - if (count_subscribed == 1) { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - } - if (count_subscribed == 8 && count_unsubscribe == 7) { - subscription_accepted_synchronous_ = true; - } - ret = true; - } else if (testmode_ == pending_subscription_test::test_mode_e::SUBSCRIBE_RESUBSCRIBE_MIXED) { - static int was_called = 0; - was_called++; - EXPECT_EQ(1, was_called); - EXPECT_TRUE(_subscribed); - subscription_accepted_synchronous_ = true; - ret = true; - } - return ret; - } - -private: - struct pending_subscription_test::service_info service_info_; - pending_subscription_test::test_mode_e testmode_; - std::shared_ptr app_; - - bool wait_until_registered_; - bool wait_until_shutdown_method_called_; - std::mutex mutex_; - std::condition_variable condition_; - std::atomic subscription_accepted_asynchronous_; - std::atomic subscription_accepted_synchronous_; - std::thread offer_thread_; - std::function async_subscription_handler_; - std::promise notify_method_called_; -}; - -pending_subscription_test::test_mode_e its_testmode(pending_subscription_test::test_mode_e::SUBSCRIBE); - -TEST(someip_pending_subscription_test, block_subscription_handler) -{ - pending_subscription_test_service its_sample(pending_subscription_test::service, its_testmode); -} - - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if (argc < 2) { - std::cerr << "Please pass a test mode to this binary like: " - << argv[0] << " SUBSCRIBE" << std::endl; - std::cerr << "Testmodes are [SUBSCRIBE, SUBSCRIBE_UNSUBSCRIBE, UNSUBSCRIBE, SUBSCRIBE_UNSUBSCRIBE_NACK, SUBSCRIBE_UNSUBSCRIBE_SAME_PORT]" << std::endl; - exit(1); - } - - std::string its_pased_testmode = argv[1]; - if (its_pased_testmode == std::string("SUBSCRIBE")) { - its_testmode = pending_subscription_test::test_mode_e::SUBSCRIBE; - } else if (its_pased_testmode == std::string("SUBSCRIBE_UNSUBSCRIBE")) { - its_testmode = pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE; - } else if (its_pased_testmode == std::string("UNSUBSCRIBE")) { - its_testmode = pending_subscription_test::test_mode_e::UNSUBSCRIBE; - } else if (its_pased_testmode == std::string("SUBSCRIBE_UNSUBSCRIBE_NACK")) { - its_testmode = pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_NACK; - } else if (its_pased_testmode == std::string("SUBSCRIBE_UNSUBSCRIBE_SAME_PORT")) { - its_testmode = pending_subscription_test::test_mode_e::SUBSCRIBE_UNSUBSCRIBE_SAME_PORT; - } else if (its_pased_testmode == std::string("SUBSCRIBE_RESUBSCRIBE_MIXED")) { - its_testmode = pending_subscription_test::test_mode_e::SUBSCRIBE_RESUBSCRIBE_MIXED; - } else if (its_pased_testmode == std::string("SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE")) { - its_testmode = pending_subscription_test::test_mode_e::SUBSCRIBE_STOPSUBSCRIBE_SUBSCRIBE; - } else if (its_pased_testmode == std::string("REQUEST_TO_SD")) { - its_testmode = pending_subscription_test::test_mode_e::REQUEST_TO_SD; - } - - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/readme.txt b/test/readme.txt deleted file mode 100644 index 2841795..0000000 --- a/test/readme.txt +++ /dev/null @@ -1,573 +0,0 @@ -Configuration Test ------------------- -To start the configuration test from the build directory do: - -./configuration-test -someip ../config/vsomeip-test.json - -The expected output is: - -2015-02-10 08:47:31.503874 [info] Test "HOST ADDRESS" succeeded. -2015-02-10 08:47:31.507609 [info] Test "HAS CONSOLE" succeeded. -2015-02-10 08:47:31.507865 [info] Test "HAS FILE" succeeded. -2015-02-10 08:47:31.508001 [info] Test "HAS DLT" succeeded. -2015-02-10 08:47:31.508143 [info] Test "LOGFILE" succeeded. -2015-02-10 08:47:31.508315 [info] Test "LOGLEVEL" succeeded. -2015-02-10 08:47:31.508456 [info] Test "RELIABLE_TEST_1234_0022" succeeded. -2015-02-10 08:47:31.508593 [info] Test "UNRELIABLE_TEST_1234_0022" succeeded. -2015-02-10 08:47:31.508759 [info] Test "RELIABLE_TEST_1234_0023" succeeded. -2015-02-10 08:47:31.508896 [info] Test "UNRELIABLE_TEST_1234_0023" succeeded. -2015-02-10 08:47:31.509032 [info] Test "RELIABLE_TEST_2277_0022" succeeded. -2015-02-10 08:47:31.509185 [info] Test "UNRELIABLE_TEST_2277_0022" succeeded. -2015-02-10 08:47:31.509330 [info] Test "RELIABLE_TEST_4466_0321" succeeded. -2015-02-10 08:47:31.509467 [info] Test "UNRELIABLE_TEST_4466_0321" succeeded. -2015-02-10 08:47:31.509602 [info] Test "RELIABLE_TEST_2277_0022" succeeded. -2015-02-10 08:47:31.509771 [info] Test "UNRELIABLE_TEST_2277_0022" succeeded. -2015-02-10 08:47:31.509915 [info] Test "ADDRESS_TEST_1234_0022" succeeded. -2015-02-10 08:47:31.510049 [info] Test "MIN_INITIAL_DELAY_TEST_1234_0022" succeeded. -2015-02-10 08:47:31.510354 [info] Test "MAX_INITIAL_DELAY_TEST_1234_0022" succeeded. -2015-02-10 08:47:31.510610 [info] Test "REPETITION_BASE_DELAY_TEST_1234_0022" succeeded. -2015-02-10 08:47:31.513978 [info] Test "REPETITION_MAX_TEST_1234_0022" succeeded. -2015-02-10 08:47:31.514177 [info] Test "CYCLIC_OFFER_DELAY_TEST_1234_0022" succeeded. -2015-02-10 08:47:31.514280 [info] Test "CYCLIC_REQUEST_DELAY_TEST_1234_0022" succeeded. -2015-02-10 08:47:31.514397 [info] Test "MIN_INITIAL_DELAY_TEST_1234_0023" succeeded. -2015-02-10 08:47:31.514618 [info] Test "MAX_INITIAL_DELAY_TEST_1234_0023" succeeded. -2015-02-10 08:47:31.514754 [info] Test "REPETITION_BASE_DELAY_TEST_1234_0023" succeeded. -2015-02-10 08:47:31.514901 [info] Test "REPETITION_MAX_TEST_1234_0023" succeeded. -2015-02-10 08:47:31.515052 [info] Test "CYCLIC_OFFER_DELAY_TEST_1234_0023" succeeded. -2015-02-10 08:47:31.515186 [info] Test "CYCLIC_REQUEST_DELAY_TEST_1234_0023" succeeded. -2015-02-10 08:47:31.515325 [info] Test "MIN_INITIAL_DELAY_TEST_2277_0022" succeeded. -2015-02-10 08:47:31.515395 [info] Test "MAX_INITIAL_DELAY_TEST_2277_0022" succeeded. -2015-02-10 08:47:31.515536 [info] Test "REPETITION_BASE_DELAY_TEST_2277_0022" succeeded. -2015-02-10 08:47:31.515691 [info] Test "REPETITION_MAX_TEST_2277_0022" succeeded. -2015-02-10 08:47:31.515834 [info] Test "CYCLIC_OFFER_DELAY_TEST_2277_0022" succeeded. -2015-02-10 08:47:31.515971 [info] Test "CYCLIC_REQUEST_DELAY_TEST_2277_0022" succeeded. -2015-02-10 08:47:31.516109 [info] Test "MIN_INITIAL_DELAY_TEST_2266_0022" succeeded. -2015-02-10 08:47:31.516279 [info] Test "MAX_INITIAL_DELAY_TEST_2266_0022" succeeded. -2015-02-10 08:47:31.516380 [info] Test "REPETITION_BASE_DELAY_TEST_2266_0022" succeeded. -2015-02-10 08:47:31.516512 [info] Test "REPETITION_MAX_TEST_2266_0022" succeeded. -2015-02-10 08:47:31.516610 [info] Test "CYCLIC_OFFER_DELAY_TEST_2266_0022" succeeded. -2015-02-10 08:47:31.516736 [info] Test "CYCLIC_REQUEST_DELAY_TEST_2266_0022" succeeded. -2015-02-10 08:47:31.516874 [info] Test "ADDRESS_TEST_4466_0321" succeeded. -2015-02-10 08:47:31.516974 [info] Test "SERVICE DISCOVERY PROTOCOL" succeeded. -2015-02-10 08:47:31.517106 [info] Test "SERVICE DISCOVERY PORT" succeeded. - - -Application test ----------------- - -This test tests starting and stopping a vsomeip application in various ways. - -Automatic start from build directory: - -ctest -V -R application_test - -Manual start from sub folder test of build directory: - -./application_test_starter.sh - - -Magic Cookies Test ------------------- -To run the magic cookies test you need two devices on the same network. The network addresses within -the configuration files need to be adapted to match the devices addresses. - -To start the magic-cookies-test from the build-directory do: - -Automatic start from build directory: - -ctest -V -R magic_cookies_test - -Manual start from sub folder test of build directory: - -# On external host run -./magic_cookies_test_service_start.sh - -# On local host run -./magic_cookies_test_client_start.sh - - -The expected result is an output like this on service side: - -2015-02-10 08:42:07.317695 [info] Received a message with Client/Session [1343/0001] -2015-02-10 08:42:07.360105 [error] Detected Magic Cookie within message data. Resyncing. -2015-02-10 08:42:07.360298 [info] Received a message with Client/Session [1343/0003] -2015-02-10 08:42:07.360527 [error] Detected Magic Cookie within message data. Resyncing. -2015-02-10 08:42:07.360621 [error] Detected Magic Cookie within message data. Resyncing. -2015-02-10 08:42:07.360714 [info] Received a message with Client/Session [1343/0006] -2015-02-10 08:42:07.360850 [info] Received a message with Client/Session [1343/0007] -2015-02-10 08:42:07.361021 [error] Detected Magic Cookie within message data. Resyncing. -2015-02-10 08:42:07.361107 [error] Detected Magic Cookie within message data. Resyncing. -2015-02-10 08:42:07.361191 [error] Detected Magic Cookie within message data. Resyncing. -2015-02-10 08:42:07.361276 [info] Received a message with Client/Session [1343/000b] -2015-02-10 08:42:07.361434 [info] Received a message with Client/Session [1343/000c] -2015-02-10 08:42:07.361558 [info] Received a message with Client/Session [1343/000d] -2015-02-10 08:42:07.361672 [error] Detected Magic Cookie within message data. Resyncing. -2015-02-10 08:42:07.361761 [info] Received a message with Client/Session [1343/000f] - -Header Factory Tests --------------------- - -The following things are tested: -a) create request - --> check "Protocol Version" / "Message Type" / "Return Type" fields -b) create request, fill header, create response - --> compare header fields of request & response -c) create notification - --> check "Protocol Version" / "Message Type" / "Return Type" fields -d) create message, fill header (service/instance/method/interface version/message type) - --> send message 10 times - --> receive message and check client id / session id - -a) to c) are combined in one binary. d) is composed out of a client and service. - -To start the header factory tests from the build directory do: - -Automatic start from build directory: -ctest -V -R header_factory_test - -Manual start from build directory: -cd test -./header_factory_test -# Start client and service separately -./header_factory_test_service_start.sh & -./header_factory_test_client_start.sh -# Alternatively start client and service with one script -./header_factory_test_send_receive_starter.sh - -All tests should be marked as "passed". - -Routing Tests -------------- - -The following things are tested: -a) create a service instance - - check that it is accessible from a local client but invisible for an external client -b) create a service instance, configure it to be externally visible - - check that it is accessible from a local client and from a external client - -a) and b) are composed out of a service each and one common client binary which is used -with different configuration files. - -Automatic start from build directory: - -ctest -V -R local_routing_test - -A message will be shown when the external client should be started. - -Manual start from build directory: -cd test -# First part with local client -# Start client and service with one script -./local_routing_test_starter.sh - -# Alternatively start client and service separately -# Warning some checks are done within the *_starter.sh script. -# This should only be used for debugging -# Start the service -./local_routing_test_service_start.sh & -# Start the client -./local_routing_test_client_start.sh - -# Second part with external client -# Start client and service with one script -./external_local_routing_test_starter.sh -# Start the external client from an external host when the message is displayed to start it -./external_local_routing_test_client_external_start.sh - -# Alternatively start client and service separately -# Warning some checks are done within the *_starter.sh script. -# This should only be used for debugging -# Start the service -./external_local_routing_test_service_start.sh & -# Start the client -./local_routing_test_client_start.sh -# Start the external client from an external host after local client has finished -./external_local_routing_test_client_external_start.sh - - -All tests should be marked as "passed". - -Payload Tests -------------- - -The following things are tested: -a) create a local service - - send messages with payloads of different size from a local client to the service - - check that the messages are received correctly - - measure the throughput -b) create a service instance, configure it to be externally visible - - send messages with payloads of different size from a local client to the service - - check that the messages are received correctly - - measure the throughput -c) create a service instance, configure it to be externally visible - - send messages with payloads of different size from an external client to the service - - check that the messages are received correctly - - measure the throughput -d) create a service instance, configure it to be externally visible - - send messages with payloads of different size from a local client to the service - - send messages with payloads of different size from an external client to the service - - check that the messages are received correctly - - measure the throughput - -The tests a) to d) are composed out of a service and a client binary which are called -with different configuration files and parameters. - -Automatic start from build directory: - -ctest -V -R payload_test - -A message will be shown when the external clients should be started. - -Manual start from build directory: -cd test - -# First part with local client -# start client and service with one script -./local_payload_test_starter.sh - -# Alternatively start client and service separately -# Warning some checks are done within the *_starter.sh script. -# This should only be used for debugging -./local_payload_test_service_start.sh & -./local_payload_test_client_start.sh - -# Second part with external visible service and local client -# start client and service with one script -./external_local_payload_test_client_local_starter.sh - -# Alternatively start client and service separately -# Warning some checks are done within the *_starter.sh script. -# This should only be used for debugging -./external_local_payload_test_service_start.sh & -./external_local_payload_test_client_local_start.sh - -# Third part with external visible service and external client -# start client and service with one script -./external_local_payload_test_client_external_starter.sh -# Start the external client from an external host if asked to -./external_local_payload_test_client_external_start.sh - -# Alternatively start client and service separately -# Warning some checks are done within the *_starter.sh script. -# This should only be used for debugging -./external_local_payload_test_service_client_external_start.sh -# Start the external client from an external host -./external_local_payload_test_client_external_start.sh - -# Fourth part with external visible service and local and external client -# start client and service with one script -./external_local_payload_test_client_local_and_external_starter.sh -# Start the external client from an external host if asked to -./external_local_payload_test_client_external_start.sh - -# Alternatively start client and service separately -# Warning some checks are done within the *_starter.sh script. -# This should only be used for debugging -./external_local_payload_test_service_client_external_start.sh & -# Start the local client -VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_local \ -VSOMEIP_CONFIGURATION=external_local_payload_test_client_local.json \ -./payload_test_client --dont-shutdown-service -# Start the external client after the local client is finished from an -# external host -./external_local_payload_test_client_external_start.sh - -All tests should be marked as "passed". - - -Big payload tests ------------------ - -This test tests the possibility to sent messages with bigger payloads -for local and TCP communication. - -The test will send a messages with 600k payload from a client to a service. -The service will reply with a response containing 600k payload as well. -This is repeated 10 times. -There is a version for local and for TCP communication available. -Additionally there are test versions available which sent up to 10MiB big -messages and a version which tests the limitiation of message sizes configurable -via json file. - -Automatic start from the build directory: - -ctest -V -R big_payload_test_local - -Manual start from sub folder test of build directory: - -./big_payload_test_service_local_start.sh & -./big_payload_test_client_local_start.sh - - -Automatic start of the TCP version from the build directory: - -ctest -V -R big_payload_test_external - -Manual start from sub folder test of build directory: - -./big_payload_test_client_start.sh - -# On external host run -./big_payload_test_service_external_start.sh - - -Client ID tests ---------------- - -This tests tests communication over two nodes with multiple services on both -nodes. - -The test setup is as followed: -* There are six services with one method each. -* Three of the services run on node 1. -* Three of the services run on node 2. -* Each of the services sends ten requests to the other services and waits - until it received a response for every request. -* If all responses have been received, the service shutdown. - -Automatic start from the build directory: - -ctest -V -R client_id_test_diff_client_ids_diff_ports - -Manual start from sub folder test of build directory: - -./client_id_test_master_starter.sh client_id_test_diff_client_ids_diff_ports_master.json - -Second version where all services on one node use the same port: - -Automatic start from the build directory: - -ctest -V -R client_id_test_diff_client_ids_same_ports - -Manual start from sub folder test of build directory: - -./client_id_test_master_starter.sh client_id_test_diff_client_ids_same_ports_master.json - - -Subscribe notify tests ----------------------- -This tests tests subscribe notify mechanism over two nodes with multiple services -on both nodes. - -The test setup is as followed: -* There are six services offering one event each. -* Three of the services run on node 1. -* Three of the services run on node 2. -* Each of the services waits until all other services are available. -* Each of the services subscribes to the offered event of all the other services. -* Each of the services then waits until the other services have subscribed to - its event. -* Each of the services then starts to sent out ten notifications for its event. -* Each service waits until it received the correct amount of notifications from - all other services. -* If all notifications have been received, the service shuts down. - -Automatic start from the build directory (example): - -ctest -V -R subscribe_notify_test_diff_client_ids_diff_ports_udp - -Manual start from sub folder test of build directory: - -./subscribe_notify_test_master_starter.sh UDP subscribe_notify_test_diff_client_ids_diff_ports_master.json - -There are multiple versions of this test which differ in the used subscription -method and port setup (use ctest -N to see all). For manual start the desired -description method has to be passed to the starter script as first parameter. - -The subscribe_notify_test_one_event_two_eventgroups_* tests are testing the -requirement that for events which are member of multiple eventgroups initial -events shall be sent per eventgroup. However normal updates of the event should -be sent only once even if a remote subscriber is subscribed to multiple of the -event's eventgroups (TR_SOMEIP_00570). - - -CPU load test -------------- -This test does a increasing number of synchronous function calls to the same -method of the service and measures CPU load for each batch of function calls. -All method calls transport a payload of 40 Bytes. The responses don't transport -any payload. - -The CPU load is measured thorugh the proc fs. -If the test prints a message like: - - Synchronously sent 0890 messages. CPU load [%]: 12.68 - -This means that the test process consumed 12% of the jiffies consumed by -complete system while doing 890 methodcalls. - -Automatic start from the build directory (example): - -ctest -V -R cpu_load_test - - -Initial event tests ----------------------- -This tests tests initial event mechanism over two nodes with multiple services -on both nodes. - -The test setup is as followed: -* There are six services offering one event each. -* Three of the services run on node 1. -* Three of the services run on node 2. -* All of the services initially set their event to their service id and notify - once -* On each node there are 20 client applications which subscribe to all of the - services events which are started at different times -* Each client waits until it received one notification (the initial one) from - all services and then exits. -* If all clients exited, the services are killed as well - -Automatic start from the build directory (example): - -ctest -V -R initial_event_test_diff_client_ids_diff_ports_udp - -Manual start from sub folder test of build directory: -./initial_event_test_master_starter.sh UDP initial_event_test_diff_client_ids_diff_ports_master.json - -There are multiple versions of this test which differ in the used subscription -method and port setup (use ctest -N to see all). For manual start the desired -description method has to be passed to the starter script as first parameter. - -Offer tests ------------ -This tests test various cases of offering a service and error recovery -after an application became unresponsive - -* Rejecting offer of service instance whose hosting application is - still alive. -* Rejecting offer of service instance whose hosting application is - still alive with daemon -* Accepting offer of service instance whose hosting application - crashed with (send SIGKILL) -* Accepting offer of service instance whose hosting application became - unresponsive (SIGSTOP) -* Rejecting offers for which there is already a pending offer -* Rejecting remote offer for which there is already a local offer -* Rejecting a local offer for which there is already a remote offer - -Automatic start from the build directory (example): - -ctest -V -R offer_tests - -Manual start from sub folder test of build directory: -./offer_test_local_starter -./offer_test_external_master_starter.sh - -Tests in detail: -Rejecting offer of service instance whose hosting application is still -alive: -* start application which offers service -* start client which continuously exchanges messages with the service -* start application which offers the same service again -> should be - rejected and an error message should be printed. -* Message exchange with client application should not be interrupted. - -Rejecting offer of service instance whose hosting application is still -alive with daemon -* start daemon (needed as he has to ping the offering client) -* start application which offers service -* start client which continuously exchanges messages with the service -* start application which offers the same service again -> should be - rejected and an error message should be printed. -* Message exchange with client application should not be interrupted. - -Accepting offer of service instance whose hosting application crashed -with (send SIGKILL) -* start daemon -* start application which offers service -* start client which exchanges messages with the service -* kill application with SIGKILL -* start application which offers the same service again -> should be - accepted. -* start another client which exchanges messages with the service -* Client should now communicate with new offerer. - -Accepting offer of service instance whose hosting application became -unresponsive (SIGSTOP) -* start daemon -* start application which offers service -* Send a SIGSTOP to the service to make it unresponsive -* start application which offers the same service again -> should be - marked as PENDING_OFFER and a ping should be sent to the paused - application. -* After the timeout passed the new offer should be accepted. -* start client which exchanges messages with the service -* Client should now communicate with new offerer. - -Rejecting offers for which there is already a pending offer -* start daemon -* start application which offers service -* Send a SIGSTOP to the service to make it unresponsive -* start application which offers the same service again -> should be - marked as PENDING_OFFER and a ping should be sent to the paused - application. -* start application which offers the same service again -> should be - rejected as there is already a PENDING_OFFER pending. -* After the timeout passed the new offer should be accepted. -* start client which exchanges messages with the service -* Client should now communicate with new offerer. - -Rejecting a local offer for which there is already a remote offer: -* start daemon -* start application which offers service -* start daemon remotely -* start same application which offers the same service again remotely - -> should be rejected as there is already a service instance - running in the network - -Rejecting remote offer for which there is already a local offer -* start application which offers service -* send SD message trying to offer the same service instance as already - offered locally from a remote host -> should be rejected - -nPDU tests ------------------ - -This test is intended to test the functionality of the so called nPDU -feature. The test setup is as followed: - -* There are two nodes, one hosting the services, one hosting the clients. -* On each of the nodes is a routing manager daemon (RMD) started whose only - purpose is to provide routing manager functionality and shutdown the clients - and services at the end. -* There are four services created. Each of the services has four methods. -* All services are listening on the same port. Therefore there only is: - * one server endpoint created in the RMD on service side - * one client endpoint created in the RMD on client side -* There are four clients created. Each of the clients will: - * Create a thread for each service - * Create a thread for each method of each service - * Send multiple messages with increasing payload to each of the services' - methods from the corresponding thread. - * After sending the threads will sleep the correct amount of time to insure - applicative debounce > debounce time + max retention time. -* After all messages have been sent to the services the clients will notify the - RMD that they're finished. The RMD then instructs the RMD on service side to - shutdown the services and exit afterwards. After that the RMD on client side - exits as well. -* Upon receiving a method call the service will check if the debounce time - specified in the json file for this method was undershot and print out a - warning. -* The test first runs in synchronous mode and waits for a response of the - service before sending the next message. -* After that the test runs in a mode where no response from the service are - required (message type REQUEST_NO_RETURN) thus the clients send at maximum - allowed frequency. - -Automatic start from build directory: - -ctest -V -R npdu_test_UDP -ctest -V -R npdu_test_TCP - -A message will be shown when the external clients should be started. - -Manual start: -# Service side -./npdu_test_service_npdu_start.sh - -# Client side UDP mode -./npdu_test_client_npdu_start.sh UDP - -# Client side TCP mode -./npdu_test_client_npdu_start.sh TCP diff --git a/test/restart_routing_tests/restart_routing_test_autoconfig.json b/test/restart_routing_tests/restart_routing_test_autoconfig.json deleted file mode 100644 index f50dba7..0000000 --- a/test/restart_routing_tests/restart_routing_test_autoconfig.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "unicast" : "127.0.0.1", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "warning", - "console" : "true", - "file" : - { - "enable" : "true", - "path" : "/var/log/vsomeip.log" - }, - - "dlt" : "true" - }, - - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30491", - "protocol" : "udp" - } -} diff --git a/test/restart_routing_tests/restart_routing_test_client.cpp b/test/restart_routing_tests/restart_routing_test_client.cpp deleted file mode 100644 index 847594e..0000000 --- a/test/restart_routing_tests/restart_routing_test_client.cpp +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "restart_routing_test_client.hpp" - -routing_restart_test_client::routing_restart_test_client() - : app_(vsomeip::runtime::get()->create_application()), - is_available_(false), - sender_(std::bind(&routing_restart_test_client::run, this)), - received_responses_(0) { - -} - -bool routing_restart_test_client::init() { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - - app_->register_state_handler( - std::bind(&routing_restart_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, - std::bind(&routing_restart_test_client::on_message, this, - std::placeholders::_1)); - - app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - std::bind(&routing_restart_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - return true; -} - -void routing_restart_test_client::start() { - VSOMEIP_INFO << "Starting..."; - - app_->start(); -} - -void routing_restart_test_client::stop() { - VSOMEIP_INFO << "Stopping..."; - - shutdown_service(); - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - app_->clear_all_handler(); - app_->stop(); -} - -void routing_restart_test_client::on_state(vsomeip::state_type_e _state) { - if(_state == vsomeip::state_type_e::ST_REGISTERED) { - app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); - } -} - -void routing_restart_test_client::on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - - VSOMEIP_INFO << std::hex << "Client 0x" << app_->get_client() - << " : Service [" << std::setw(4) << std::setfill('0') << std::hex - << _service << "." << _instance << "] is " - << (_is_available ? "available." : "NOT available."); - - if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service - && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) { - std::unique_lock its_lock(mutex_); - if(is_available_ && !_is_available) { - is_available_ = false; - } - else if(_is_available && !is_available_) { - is_available_ = true; - condition_.notify_one(); - } - } -} - -void routing_restart_test_client::on_message(const std::shared_ptr &_response) { - VSOMEIP_INFO << "Received a response from Service [" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() - << "." - << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() - << "] to Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() - << "/" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() - << "]"; - - if (_response->get_service() == vsomeip_test::TEST_SERVICE_SERVICE_ID && - _response->get_instance() == vsomeip_test::TEST_SERVICE_INSTANCE_ID) { - received_responses_++; - if (received_responses_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS) { - VSOMEIP_WARNING << std::hex << app_->get_client() - << ": Received all messages ~> going down!"; - all_responses_received_.set_value(); - } - } -} - -void routing_restart_test_client::run() { - for (uint32_t i = 0; i < vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS; ++i) { - { - std::unique_lock its_lock(mutex_); - while (!is_available_) - { - condition_.wait(its_lock); - } - } - - auto request = vsomeip::runtime::get()->create_request(false); - request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); - app_->send(request); - - std::this_thread::sleep_for(std::chrono::milliseconds(250)); - } - - if (std::future_status::ready == all_responses_received_.get_future().wait_for(std::chrono::milliseconds(10000))) { - EXPECT_EQ(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS, - received_responses_); - VSOMEIP_WARNING << "Received all answers"; - } else { - ADD_FAILURE() << "Didn't receive all responses within time"; - } - - stop(); -} - -void routing_restart_test_client::join_sender_thread() -{ - if (sender_.joinable()) { - sender_.join(); - } -} - -void routing_restart_test_client::shutdown_service() { - auto request = vsomeip::runtime::get()->create_request(false); - request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); - app_->send(request); -} - -TEST(someip_restart_routing_test, request_response_over_restart) -{ - routing_restart_test_client test_client; - if (test_client.init()) { - test_client.start(); - test_client.join_sender_thread(); - } -} - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/restart_routing_tests/restart_routing_test_client.hpp b/test/restart_routing_tests/restart_routing_test_client.hpp deleted file mode 100644 index cd4a12f..0000000 --- a/test/restart_routing_tests/restart_routing_test_client.hpp +++ /dev/null @@ -1,52 +0,0 @@ - -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef RESTART_ROUTING_TEST_CLIENT_HPP -#define RESTART_ROUTING_TEST_CLIENT_HPP - -#include - -#include - -#include "../someip_test_globals.hpp" - -#include -#include -#include -#include -#include - -class routing_restart_test_client { -public: - routing_restart_test_client(); - bool init(); - void start(); - void stop(); - - void on_state(vsomeip::state_type_e _state); - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available); - void on_message(const std::shared_ptr &_response); - - void run(); - void join_sender_thread(); - -private: - void shutdown_service(); - - std::shared_ptr app_; - - std::mutex mutex_; - std::condition_variable condition_; - bool is_available_; - - std::thread sender_; - - std::atomic received_responses_; - std::promise all_responses_received_; -}; - -#endif // RESTART_ROUTING_TEST_CLIENT_HPP diff --git a/test/restart_routing_tests/restart_routing_test_client.json b/test/restart_routing_tests/restart_routing_test_client.json deleted file mode 100644 index 93fafab..0000000 --- a/test/restart_routing_tests/restart_routing_test_client.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "unicast" : "127.0.0.1", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "warning", - "console" : "true", - "file" : - { - "enable" : "true", - "path" : "/var/log/vsomeip.log" - }, - - "dlt" : "true" - }, - - "applications" : - [ - { - "name" : "restart_routing_test_client1", - "id" : "0x1343" - }, - { - "name" : "restart_routing_test_client2", - "id" : "0x1344" - }, - { - "name" : "restart_routing_test_client3", - "id" : "0x1345" - }, - { - "name" : "restart_routing_test_client4", - "id" : "0x1346" - } - ], - "services" : - [ - ], - - "routing" : "routingmanagerd", - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30491", - "protocol" : "udp" - } -} diff --git a/test/restart_routing_tests/restart_routing_test_client_start.sh b/test/restart_routing_tests/restart_routing_test_client_start.sh deleted file mode 100755 index de944b9..0000000 --- a/test/restart_routing_tests/restart_routing_test_client_start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client -export VSOMEIP_CONFIGURATION=restart_routing_test_client.json -./restart_routing_test_client diff --git a/test/restart_routing_tests/restart_routing_test_service.cpp b/test/restart_routing_tests/restart_routing_test_service.cpp deleted file mode 100644 index 35ab01a..0000000 --- a/test/restart_routing_tests/restart_routing_test_service.cpp +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "restart_routing_test_service.hpp" - -routing_restart_test_service::routing_restart_test_service() : - app_(vsomeip::runtime::get()->create_application()), - is_registered_(false), - blocked_(false), - number_of_received_messages_(0), - offer_thread_(std::bind(&routing_restart_test_service::run, this)) { -} - -bool routing_restart_test_service::init() { - std::lock_guard its_lock(mutex_); - - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, - std::bind(&routing_restart_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, - std::bind(&routing_restart_test_service::on_message_shutdown, this, - std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&routing_restart_test_service::on_state, this, - std::placeholders::_1)); - return true; -} - -void routing_restart_test_service::start() { - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void routing_restart_test_service::stop() { - VSOMEIP_INFO << "Stopping..."; - app_->clear_all_handler(); - app_->stop(); -} - -void routing_restart_test_service::join_offer_thread() { - if (offer_thread_.joinable()) { - offer_thread_.join(); - } -} - -void routing_restart_test_service::offer() { - app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void routing_restart_test_service::stop_offer() { - app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void routing_restart_test_service::on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : - "deregistered."); - - if(_state == vsomeip::state_type_e::ST_REGISTERED) { - if(!is_registered_) { - is_registered_ = true; - std::lock_guard its_lock(mutex_); - blocked_ = true; - // "start" the run method thread - condition_.notify_one(); - } - } - else { - is_registered_ = false; - } -} - -void routing_restart_test_service::on_message(const std::shared_ptr& _request) { - ASSERT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _request->get_service()); - ASSERT_EQ(vsomeip_test::TEST_SERVICE_METHOD_ID, _request->get_method()); - - VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _request->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _request->get_session() << "]"; - - // send response - std::shared_ptr its_response = - vsomeip::runtime::get()->create_response(_request); - - app_->send(its_response); - - number_of_received_messages_++; - if(number_of_received_messages_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS) { - VSOMEIP_INFO << "Received all messages!"; - } -} - -void routing_restart_test_service::on_message_shutdown( - const std::shared_ptr& _request) { - (void)_request; - VSOMEIP_INFO << "Shutdown method was called, going down now."; - stop(); -} - -void routing_restart_test_service::run() { - std::unique_lock its_lock(mutex_); - while (!blocked_) - condition_.wait(its_lock); - - offer(); -} - -TEST(someip_restart_routing_test, send_response_for_every_request) { - routing_restart_test_service test_service; - if (test_service.init()) { - test_service.start(); - test_service.join_offer_thread(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/restart_routing_tests/restart_routing_test_service.hpp b/test/restart_routing_tests/restart_routing_test_service.hpp deleted file mode 100644 index 3abfe17..0000000 --- a/test/restart_routing_tests/restart_routing_test_service.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef RESTART_ROUTING_TEST_SERVICE_HPP -#define RESTART_ROUTING_TEST_SERVICE_HPP - -#include - -#include - -#include "../someip_test_globals.hpp" - -#include -#include -#include - -class routing_restart_test_service { -public: - routing_restart_test_service(); - bool init(); - void start(); - void stop(); - void offer(); - void stop_offer(); - void join_offer_thread(); - void on_state(vsomeip::state_type_e _state); - void on_message(const std::shared_ptr &_request); - void on_message_shutdown(const std::shared_ptr &_request); - void run(); - -private: - std::shared_ptr app_; - bool is_registered_; - - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - std::uint32_t number_of_received_messages_; - std::thread offer_thread_; -}; - -#endif // RESTART_ROUTING_TEST_SERVICE_HPP diff --git a/test/restart_routing_tests/restart_routing_test_service.json b/test/restart_routing_tests/restart_routing_test_service.json deleted file mode 100644 index 9a1d3bf..0000000 --- a/test/restart_routing_tests/restart_routing_test_service.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "unicast" : "127.0.0.1", - "logging" : - { - "level" : "warning", - "console" : "true", - "file" : - { - "enable" : "false", - "path" : "/tmp/vsomeip.log" - }, - - "dlt" : "false" - }, - - "applications" : - [ - { - "name" : "routingmanagerd", - "id" : "0x0815" - }, - { - "name" : "restart_routing_test_service", - "id" : "0x1277" - } - ], - - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678" - } - ], - - "routing" : "routingmanagerd", - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp" - } -} diff --git a/test/restart_routing_tests/restart_routing_test_service_start.sh b/test/restart_routing_tests/restart_routing_test_service_start.sh deleted file mode 100755 index b82be7c..0000000 --- a/test/restart_routing_tests/restart_routing_test_service_start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=restart_routing_test_service -export VSOMEIP_CONFIGURATION=restart_routing_test_service.json -./restart_routing_test_service diff --git a/test/restart_routing_tests/restart_routing_test_starter.sh b/test/restart_routing_tests/restart_routing_test_starter.sh deleted file mode 100755 index 9d74c36..0000000 --- a/test/restart_routing_tests/restart_routing_test_starter.sh +++ /dev/null @@ -1,312 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -FAIL=0 - -# NOW WITHOUT JSON -echo "----------------------------------------------" -echo "----------------------------------------------" -echo " Run test with auto configuration " -echo "----------------------------------------------" -echo "----------------------------------------------" - -export VSOMEIP_CONFIGURATION=restart_routing_test_autoconfig.json - -../examples/routingmanagerd/./routingmanagerd & -DAEMON_PID=$! - -sleep 2 - -# Start the service -export VSOMEIP_APPLICATION_NAME=restart_routing_test_service -./restart_routing_test_service & -SERIVCE_PID=$! - -# Start the client1 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client1 -./restart_routing_test_client & -CLIENT1_PID=$! - -# Start the client2 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client2 -./restart_routing_test_client & -CLIENT2_PID=$! - -# Start the client3 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client3 -./restart_routing_test_client & -CLIENT3_PID=$! - -# Start the client4 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client4 -./restart_routing_test_client & -CLIENT4_PID=$! - -sleep 2 -echo "----------------------------------------------" -echo " let routingmanagerd crash (kill -9) " -echo "----------------------------------------------" -kill -9 $DAEMON_PID -echo "----------------------------------------------" -echo " restart routingmanagerd " -echo "----------------------------------------------" -sleep 2 - -../examples/routingmanagerd/./routingmanagerd & -DAEMON_PID=$! - -wait $SERIVCE_PID || ((FAIL+=1)) -wait $CLIENT1_PID || ((FAIL+=1)) -wait $CLIENT2_PID || ((FAIL+=1)) -wait $CLIENT3_PID || ((FAIL+=1)) -wait $CLIENT4_PID || ((FAIL+=1)) - -kill $DAEMON_PID -wait $DAEMON_PID - -# Check if client and server both exited sucessfully and the service didnt't -# have any open tcp/udp sockets -if [ $FAIL -eq 0 ] -then - echo "Test Succeeded" -else - exit 1 -fi - -# NOW WITHOUT VSOMEIPD -echo "----------------------------------------------" -echo "----------------------------------------------" -echo " Run test with auto configuration no deamon " -echo "----------------------------------------------" -echo "----------------------------------------------" - -sleep 2 - -# Start the service -export VSOMEIP_APPLICATION_NAME=restart_routing_test_service -./restart_routing_test_service & -SERIVCE_PID=$! - -# Start the client1 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client1 -./restart_routing_test_client & -CLIENT1_PID=$! - -# Start the client2 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client2 -./restart_routing_test_client & -CLIENT2_PID=$! - -# Start the client3 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client3 -./restart_routing_test_client & -CLIENT3_PID=$! - -# Start the client4 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client4 -./restart_routing_test_client & -CLIENT4_PID=$! - -sleep 2 -echo "----------------------------------------------" -echo " let service (routing) crash (kill -9) " -echo "----------------------------------------------" -kill -9 $SERIVCE_PID -echo "----------------------------------------------" -echo " restart service (routing) " -echo "----------------------------------------------" -sleep 2 - -# Start the service -export VSOMEIP_APPLICATION_NAME=restart_routing_test_service -./restart_routing_test_service & -SERIVCE_PID=$! - -wait $SERIVCE_PID || ((FAIL+=1)) -wait $CLIENT1_PID || ((FAIL+=1)) -wait $CLIENT2_PID || ((FAIL+=1)) -wait $CLIENT3_PID || ((FAIL+=1)) -wait $CLIENT4_PID || ((FAIL+=1)) - -# Check if client and server both exited sucessfully and the service didnt't -# have any open tcp/udp sockets -if [ $FAIL -eq 0 ] -then - echo "Test Succeeded" -else - exit 1 -fi - - -echo "----------------------------------------------" -echo "----------------------------------------------" -echo " Run test with json configuration " -echo "----------------------------------------------" -echo "----------------------------------------------" - -sleep 2 - -export VSOMEIP_CONFIGURATION=restart_routing_test_service.json -../examples/routingmanagerd/./routingmanagerd & -DAEMON_PID=$! - -# Start the service -export VSOMEIP_APPLICATION_NAME=restart_routing_test_service -export VSOMEIP_CONFIGURATION=restart_routing_test_service.json -./restart_routing_test_service & -SERIVCE_PID=$! - -# Start the client1 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client1 -export VSOMEIP_CONFIGURATION=restart_routing_test_client.json -./restart_routing_test_client & -CLIENT1_PID=$! - -# Start the client2 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client2 -export VSOMEIP_CONFIGURATION=restart_routing_test_client.json -./restart_routing_test_client & -CLIENT2_PID=$! - -# Start the client3 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client3 -export VSOMEIP_CONFIGURATION=restart_routing_test_client.json -./restart_routing_test_client & -CLIENT3_PID=$! - -# Start the client4 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client4 -export VSOMEIP_CONFIGURATION=restart_routing_test_client.json -./restart_routing_test_client & -CLIENT4_PID=$! - -sleep 2 -echo "----------------------------------------------" -echo " let routingmanagerd crash (kill -9) " -echo "----------------------------------------------" -kill -9 $DAEMON_PID -echo "----------------------------------------------" -echo " restart routingmanagerd " -echo "----------------------------------------------" -sleep 2 - -export VSOMEIP_CONFIGURATION=restart_routing_test_service.json -../examples/routingmanagerd/./routingmanagerd & -DAEMON_PID=$! - -wait $SERIVCE_PID || ((FAIL+=1)) -wait $CLIENT1_PID || ((FAIL+=1)) -wait $CLIENT2_PID || ((FAIL+=1)) -wait $CLIENT3_PID || ((FAIL+=1)) -wait $CLIENT4_PID || ((FAIL+=1)) - -kill $DAEMON_PID -wait $DAEMON_PID - -# Check if client and server both exited sucessfully and the service didnt't -# have any open tcp/udp sockets -if [ $FAIL -eq 0 ] -then - echo "Test Succeeded" -else - exit 1 -fi - -echo "----------------------------------------------" -echo "----------------------------------------------" -echo "Run test with json configuration + kill service" -echo "----------------------------------------------" -echo "----------------------------------------------" - -sleep 2 - -export VSOMEIP_CONFIGURATION=restart_routing_test_service.json -../examples/routingmanagerd/./routingmanagerd & -DAEMON_PID=$! - -# Start the service -export VSOMEIP_APPLICATION_NAME=restart_routing_test_service -export VSOMEIP_CONFIGURATION=restart_routing_test_service.json -./restart_routing_test_service & -SERIVCE_PID=$! - -# Start the client1 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client1 -export VSOMEIP_CONFIGURATION=restart_routing_test_client.json -./restart_routing_test_client & -CLIENT1_PID=$! - -# Start the client2 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client2 -export VSOMEIP_CONFIGURATION=restart_routing_test_client.json -./restart_routing_test_client & -CLIENT2_PID=$! - -# Start the client3 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client3 -export VSOMEIP_CONFIGURATION=restart_routing_test_client.json -./restart_routing_test_client & -CLIENT3_PID=$! - -# Start the client4 -export VSOMEIP_APPLICATION_NAME=restart_routing_test_client4 -export VSOMEIP_CONFIGURATION=restart_routing_test_client.json -./restart_routing_test_client & -CLIENT4_PID=$! - -sleep 2 -echo "----------------------------------------------" -echo " let routingmanagerd crash (kill -9) " -echo "----------------------------------------------" -kill -9 $DAEMON_PID -sleep 1 -echo "----------------------------------------------" -echo " let service crash (kill -9) " -echo "----------------------------------------------" -kill -9 $SERIVCE_PID -echo "----------------------------------------------" -echo " restart routingmanagerd " -echo "----------------------------------------------" -sleep 2 - -export VSOMEIP_CONFIGURATION=restart_routing_test_service.json -../examples/routingmanagerd/./routingmanagerd & -DAEMON_PID=$! - -echo "----------------------------------------------" -echo " restart service " -echo "----------------------------------------------" -sleep 1 - -# Start the service again -export VSOMEIP_APPLICATION_NAME=restart_routing_test_service -export VSOMEIP_CONFIGURATION=restart_routing_test_service.json -./restart_routing_test_service & -SERIVCE_PID=$! - -wait $SERIVCE_PID || ((FAIL+=1)) -wait $CLIENT1_PID || ((FAIL+=1)) -wait $CLIENT2_PID || ((FAIL+=1)) -wait $CLIENT3_PID || ((FAIL+=1)) -wait $CLIENT4_PID || ((FAIL+=1)) - -kill $DAEMON_PID -wait $DAEMON_PID - -# Check if client and server both exited sucessfully and the service didnt't -# have any open tcp/udp sockets -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/routing_tests/conf/external_local_routing_test_client_external.json.in b/test/routing_tests/conf/external_local_routing_test_client_external.json.in deleted file mode 100644 index 958f196..0000000 --- a/test/routing_tests/conf/external_local_routing_test_client_external.json.in +++ /dev/null @@ -1,44 +0,0 @@ -{ - "unicast" : "@TEST_IP_SLAVE@", - "netmask" : "255.255.255.0", - "diagnosis" : "0x16", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "true", - "path" : "/var/log/vsomeip.log" - }, - - "dlt" : "true" - }, - - "applications" : - [ - { - "name" : "external_local_routing_test_client_external", - "id" : "0x1644" - } - ], - - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509" - } - ], - - "routing" : "external_local_routing_test_client_external", - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30491", - "protocol" : "udp" - } -} diff --git a/test/routing_tests/conf/external_local_routing_test_service.json.in b/test/routing_tests/conf/external_local_routing_test_service.json.in deleted file mode 100644 index a4deb82..0000000 --- a/test/routing_tests/conf/external_local_routing_test_service.json.in +++ /dev/null @@ -1,42 +0,0 @@ -{ - "unicast" : "@TEST_IP_MASTER@", - "diagnosis":"0x12", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "false", - "path" : "/tmp/vsomeip.log" - }, - - "dlt" : "false" - }, - - "applications" : - [ - { - "name" : "external_local_routing_test_service", - "id" : "0x1277" - } - ], - - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678", - "unreliable" : "30509" - } - ], - - "routing" : "external_local_routing_test_service", - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp" - } -} diff --git a/test/routing_tests/conf/local_routing_test_starter.sh.bat.in b/test/routing_tests/conf/local_routing_test_starter.sh.bat.in deleted file mode 100755 index d7abe64..0000000 --- a/test/routing_tests/conf/local_routing_test_starter.sh.bat.in +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -FAIL=0 - -# Parameter 1: the pid to check -check_tcp_udp_sockets_are_closed () -{ - # Check that the service does not listen on any TCP/UDP socket - # or has any active connection via a TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] - then - ((FAIL+=1)) - fi - - SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] - then - ((FAIL+=1)) - fi -} - -# Start the service -export VSOMEIP_APPLICATION_NAME=local_routing_test_service -if [ "$VSOMEIP_CONFIGURATION_SERVICE" != "" ] -then - export VSOMEIP_CONFIGURATION=$VSOMEIP_CONFIGURATION_SERVICE -else - export VSOMEIP_CONFIGURATION=local_routing_test_service.json -fi -./local_routing_test_service & -SERIVCE_PID=$! -sleep 1; - -check_tcp_udp_sockets_are_closed $SERIVCE_PID - -# Start the client -export VSOMEIP_APPLICATION_NAME=local_routing_test_client -if [ "$VSOMEIP_CONFIGURATION_CLIENT" != "" ] -then - export VSOMEIP_CONFIGURATION=$VSOMEIP_CONFIGURATION_CLIENT -else - export VSOMEIP_CONFIGURATION=local_routing_test_client.json -fi -./local_routing_test_client & -CLIENT_PID=$! - -check_tcp_udp_sockets_are_closed $SERIVCE_PID -check_tcp_udp_sockets_are_closed $CLIENT_PID - -# Wait until client and service are finished -for job in $(jobs -p) -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if client and server both exited successfully and the service didnt't -# have any open -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/routing_tests/conf/local_routing_test_starter.sh.in b/test/routing_tests/conf/local_routing_test_starter.sh.in deleted file mode 100755 index 9e10480..0000000 --- a/test/routing_tests/conf/local_routing_test_starter.sh.in +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -FAIL=0 - -# Parameter 1: the pid to check -check_tcp_udp_sockets_are_closed () -{ - # Check that the service does not listen on any TCP/UDP socket - # or has any active connection via a TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] - then - ((FAIL+=1)) - fi - - SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] - then - ((FAIL+=1)) - fi -} - -export VSOMEIP_CONFIGURATION=local_routing_test_service.json -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -WAIT_PIDS=() -# Start the service -export VSOMEIP_APPLICATION_NAME=local_routing_test_service -./local_routing_test_service & -SERIVCE_PID=$! -WAIT_PIDS+=($!) -sleep 1; - -check_tcp_udp_sockets_are_closed $SERIVCE_PID - -# Start the client -export VSOMEIP_APPLICATION_NAME=local_routing_test_client -export VSOMEIP_CONFIGURATION=local_routing_test_client.json -./local_routing_test_client & -CLIENT_PID=$! -WAIT_PIDS+=($!) - -check_tcp_udp_sockets_are_closed $SERIVCE_PID -check_tcp_udp_sockets_are_closed $CLIENT_PID - -# Wait until client and service are finished -for job in ${WAIT_PIDS[*]} -do - # Fail gets incremented if either client or service exit - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -kill $PID_VSOMEIPD -sleep 1 - -# Check if client and server both exited successfully and the service didnt't -# have any open -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/routing_tests/external_local_routing_test_client_external_start.sh b/test/routing_tests/external_local_routing_test_client_external_start.sh deleted file mode 100755 index b267b47..0000000 --- a/test/routing_tests/external_local_routing_test_client_external_start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=external_local_routing_test_client_external -export VSOMEIP_CONFIGURATION=external_local_routing_test_client_external.json -./local_routing_test_client diff --git a/test/routing_tests/external_local_routing_test_service.cpp b/test/routing_tests/external_local_routing_test_service.cpp deleted file mode 100644 index c357165..0000000 --- a/test/routing_tests/external_local_routing_test_service.cpp +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "external_local_routing_test_service.hpp" - -external_local_routing_test_service::external_local_routing_test_service(bool _use_static_routing) : - app_(vsomeip::runtime::get()->create_application()), - is_registered_(false), - use_static_routing_(_use_static_routing), - blocked_(false), - number_received_messages_local_(0), - number_received_messages_external_(0), - offer_thread_(std::bind(&external_local_routing_test_service::run, this)) -{ -} - -bool external_local_routing_test_service::init() -{ - std::lock_guard its_lock(mutex_); - - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, - std::bind(&external_local_routing_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, - std::bind(&external_local_routing_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&external_local_routing_test_service::on_state, this, - std::placeholders::_1)); - - VSOMEIP_INFO << "Static routing " << (use_static_routing_ ? "ON" : "OFF"); - return true; -} - -void external_local_routing_test_service::start() -{ - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void external_local_routing_test_service::stop() -{ - VSOMEIP_INFO << "Stopping..."; - app_->clear_all_handler(); - app_->stop(); -} - -void external_local_routing_test_service::join_offer_thread() -{ - offer_thread_.join(); -} - -void external_local_routing_test_service::offer() -{ - app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void external_local_routing_test_service::stop_offer() -{ - app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void external_local_routing_test_service::on_state(vsomeip::state_type_e _state) -{ - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : - "deregistered."); - - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - if(!is_registered_) - { - std::lock_guard its_lock(mutex_); - is_registered_ = true; - blocked_ = true; - // "start" the run method thread - condition_.notify_one(); - } - } - else - { - is_registered_ = false; - } -} - -void external_local_routing_test_service::on_message( - const std::shared_ptr& _request) -{ - VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _request->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _request->get_session() << "]"; - - ASSERT_EQ(_request->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID); - ASSERT_EQ(_request->get_method(), vsomeip_test::TEST_SERVICE_METHOD_ID); - - // Check the protocol version this shall be set to 0x01 according to the spec. - // TR_SOMEIP_00052 - ASSERT_EQ(_request->get_protocol_version(), 0x01); - // Check the message type this shall be 0xx (REQUEST) according to the spec. - // TR_SOMEIP_00055 - ASSERT_EQ(_request->get_message_type(), vsomeip::message_type_e::MT_REQUEST); - - if(_request->get_client() == vsomeip_test::TEST_CLIENT_CLIENT_ID) - { - number_received_messages_local_++; - // check the session id. - ASSERT_EQ(_request->get_session(), - static_cast(number_received_messages_local_)); - } - else if (_request->get_client() == vsomeip_test::TEST_CLIENT_EXTERNAL_CLIENT_ID) - { - number_received_messages_external_++; - // check the session id. - ASSERT_EQ(_request->get_session(), - static_cast(number_received_messages_external_)); - } - - // send response - std::shared_ptr its_response = - vsomeip::runtime::get()->create_response(_request); - - app_->send(its_response); - - if(number_received_messages_local_ >= vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND - && number_received_messages_external_ >= vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND) - { - std::lock_guard its_lock(mutex_); - blocked_ = true; - condition_.notify_one(); - } - ASSERT_LT(number_received_messages_local_, - vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND + 1); - ASSERT_LT(number_received_messages_external_, - vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND + 1); -} - -void external_local_routing_test_service::run() -{ - std::unique_lock its_lock(mutex_); - while (!blocked_) - condition_.wait(its_lock); - - blocked_ = false; - if(use_static_routing_) - { - offer(); - } - - while (!blocked_) { - condition_.wait(its_lock); - } - - std::thread t2([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 2));}); - t2.join(); - app_->stop(); -} - -TEST(someip_external_local_routing_test, receive_ten_messages_over_local_and_external_socket) -{ - bool use_static_routing = true; - external_local_routing_test_service test_service(use_static_routing); - if (test_service.init()) { - test_service.start(); - test_service.join_offer_thread(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/routing_tests/external_local_routing_test_service.hpp b/test/routing_tests/external_local_routing_test_service.hpp deleted file mode 100644 index a25025e..0000000 --- a/test/routing_tests/external_local_routing_test_service.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EXTERNALLOCALROUTINGTESTSERVICE_HPP_ -#define EXTERNALLOCALROUTINGTESTSERVICE_HPP_ -#include - -#include - -#include -#include -#include -#include - -#include "../someip_test_globals.hpp" - -class external_local_routing_test_service -{ -public: - external_local_routing_test_service(bool _use_static_routing); - bool init(); - void start(); - void stop(); - void offer(); - void stop_offer(); - void join_offer_thread(); - void on_state(vsomeip::state_type_e _state); - void on_message(const std::shared_ptr &_request); - void run(); - -private: - std::shared_ptr app_; - bool is_registered_; - bool use_static_routing_; - - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - std::uint32_t number_received_messages_local_; - std::uint32_t number_received_messages_external_; - std::thread offer_thread_; -}; - -#endif /* EXTERNALLOCALROUTINGTESTSERVICE_HPP_ */ diff --git a/test/routing_tests/external_local_routing_test_service_start.sh b/test/routing_tests/external_local_routing_test_service_start.sh deleted file mode 100755 index 81b2ef1..0000000 --- a/test/routing_tests/external_local_routing_test_service_start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=external_local_routing_test_service -export VSOMEIP_CONFIGURATION=external_local_routing_test_service.json -./external_local_routing_test_service diff --git a/test/routing_tests/external_local_routing_test_starter.sh b/test/routing_tests/external_local_routing_test_starter.sh deleted file mode 100755 index 7b3d37b..0000000 --- a/test/routing_tests/external_local_routing_test_starter.sh +++ /dev/null @@ -1,124 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the client and service with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start two binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs client -# and service and checks that both exit sucessfully. - -FAIL=0 - -# Parameter 1: the pid to check -check_tcp_udp_sockets_are_open () -{ - # Check that the service does listen on at least one TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -lt 1 ] - then - ((FAIL+=1)) - fi -} - -# Parameter 1: the pid to check -check_tcp_udp_sockets_are_closed () -{ - # Check that the service does not listen on any TCP/UDP socket - # or has any active connection via a TCP/UDP socket - # awk is used to avoid the case when a inode number is the same as a PID. The awk - # program filters the netstat output down to the protocol (1st field) and - # the PID/Program name (last field) fields. - SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] - then - ((FAIL+=1)) - fi - - SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) - if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] - then - ((FAIL+=1)) - fi -} - -# Start the service -export VSOMEIP_APPLICATION_NAME=external_local_routing_test_service -export VSOMEIP_CONFIGURATION=external_local_routing_test_service.json -./external_local_routing_test_service & -SERIVCE_PID=$! -sleep 1; - -check_tcp_udp_sockets_are_open $SERIVCE_PID - -# Start the client (we reuse the one from the local_routing_test to check -# the local routing functionality). -export VSOMEIP_APPLICATION_NAME=local_routing_test_client -export VSOMEIP_CONFIGURATION=local_routing_test_client.json -./local_routing_test_client & -CLIENT_PID=$! - -check_tcp_udp_sockets_are_open $SERIVCE_PID -sleep 1 -check_tcp_udp_sockets_are_closed $CLIENT_PID - -# wait that local client finishes -sleep 2 - -# Display a message to show the user that he must now call the external client -# to finish the test successfully -kill -0 $CLIENT_PID &> /dev/null -CLIENT_STILL_THERE=$? -if [ $CLIENT_STILL_THERE -ne 0 ] -then - if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting external_local_routing_test_starter.sh on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./external_local_routing_test_client_external_start.sh\"" & - echo "remote ssh job id: $!" - elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_routing_test_client_external_start.sh" & - elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./external_local_routing_test_client_external_start.sh\" >> $WS_ROOT/slave_test_output 2>&1" & - - else - cat <create_application()), - request_(vsomeip::runtime::get()->create_request(_use_tcp)), - blocked_(false), - is_available_(false), - number_of_messages_to_send_(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND), - number_of_sent_messages_(0), - number_of_acknowledged_messages_(0), - sender_(std::bind(&local_routing_test_client::run, this)) -{ -} - -bool local_routing_test_client::init() -{ - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - - app_->register_state_handler( - std::bind(&local_routing_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, - std::bind(&local_routing_test_client::on_message, this, - std::placeholders::_1)); - - app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - std::bind(&local_routing_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - return true; -} - -void local_routing_test_client::start() -{ - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void local_routing_test_client::stop() -{ - VSOMEIP_INFO << "Stopping..."; - app_->clear_all_handler(); - app_->stop(); -} - -void local_routing_test_client::join_sender_thread(){ - sender_.join(); - - ASSERT_EQ(number_of_sent_messages_, number_of_acknowledged_messages_); -} - -void local_routing_test_client::on_state(vsomeip::state_type_e _state) -{ - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); - } -} - -void local_routing_test_client::on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) -{ - VSOMEIP_INFO << "Service [" << std::setw(4) << std::setfill('0') << std::hex - << _service << "." << _instance << "] is " - << (_is_available ? "available." : "NOT available."); - - if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service - && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) - { - if(is_available_ && !_is_available) - { - is_available_ = false; - } - else if(_is_available && !is_available_) - { - is_available_ = true; - send(); - } - } -} - -void local_routing_test_client::on_message(const std::shared_ptr& _response) -{ - VSOMEIP_INFO << "Received a response from Service [" << std::setw(4) - << std::setfill('0') << std::hex << _response->get_service() << "." - << std::setw(4) << std::setfill('0') << std::hex - << _response->get_instance() << "] to Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex - << _response->get_client() << "/" << std::setw(4) - << std::setfill('0') << std::hex << _response->get_session() << "]"; - number_of_acknowledged_messages_++; - if(number_of_acknowledged_messages_ == number_of_messages_to_send_) { - std::lock_guard its_lock(mutex_); - blocked_ = true; - condition_.notify_one(); - } -} - -void local_routing_test_client::send() -{ - std::lock_guard its_lock(mutex_); - blocked_ = true; - condition_.notify_one(); -} - -void local_routing_test_client::run() -{ - std::unique_lock its_lock(mutex_); - while (!blocked_) - { - condition_.wait(its_lock); - } - blocked_ = false; - request_->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - request_->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - request_->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); - - for (uint32_t i = 0; i < number_of_messages_to_send_; i++) - { - app_->send(request_); - VSOMEIP_INFO << "Client/Session [" << std::setw(4) << std::setfill('0') - << std::hex << request_->get_client() << "/" << std::setw(4) - << std::setfill('0') << std::hex << request_->get_session() - << "] sent a request to Service [" << std::setw(4) - << std::setfill('0') << std::hex << request_->get_service() - << "." << std::setw(4) << std::setfill('0') << std::hex - << request_->get_instance() << "]"; - number_of_sent_messages_++; - } - blocked_ = false; - // wait until all messages have been acknowledged - while (!blocked_) - { - condition_.wait(its_lock); - } - stop(); -} - -TEST(someip_local_routing_test, send_ten_messages_to_service_and_receive_reply) -{ - bool use_tcp = false; - local_routing_test_client test_client_(use_tcp); - if (test_client_.init()) { - test_client_.start(); - test_client_.join_sender_thread(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/routing_tests/local_routing_test_client.hpp b/test/routing_tests/local_routing_test_client.hpp deleted file mode 100644 index 7cc442a..0000000 --- a/test/routing_tests/local_routing_test_client.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef LOCALROUTINGTESTCLIENT_HPP_ -#define LOCALROUTINGTESTCLIENT_HPP_ - -#include - -#include - -#include -#include -#include -#include - -#include "../someip_test_globals.hpp" - -class local_routing_test_client -{ -public: - local_routing_test_client(bool _use_tcp); - bool init(); - void start(); - void stop(); - void join_sender_thread(); - void on_state(vsomeip::state_type_e _state); - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available); - void on_message(const std::shared_ptr &_response); - void send(); - void run(); - -private: - std::shared_ptr app_; - std::shared_ptr request_; - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - bool is_available_; - std::uint32_t number_of_messages_to_send_; - std::uint32_t number_of_sent_messages_; - std::uint32_t number_of_acknowledged_messages_; - std::thread sender_; -}; - -#endif /* LOCALROUTINGTESTCLIENT_HPP_ */ diff --git a/test/routing_tests/local_routing_test_client.json b/test/routing_tests/local_routing_test_client.json deleted file mode 100644 index e3521c8..0000000 --- a/test/routing_tests/local_routing_test_client.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "unicast" : "127.0.0.1", - "netmask" : "255.255.255.0", - "diagnosis":"0x12", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "true", - "path" : "/var/log/vsomeip.log" - }, - - "dlt" : "true" - }, - - "applications" : - [ - { - "name" : "local_routing_test_client", - "id" : "0x1255" - } - ], - - "services" : - [ - ], - - "routing" : "routingmanagerd", - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30491", - "protocol" : "udp" - } -} \ No newline at end of file diff --git a/test/routing_tests/local_routing_test_client_start.sh b/test/routing_tests/local_routing_test_client_start.sh deleted file mode 100755 index ed4023e..0000000 --- a/test/routing_tests/local_routing_test_client_start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=local_routing_test_client -export VSOMEIP_CONFIGURATION=local_routing_test_client.json -./local_routing_test_client diff --git a/test/routing_tests/local_routing_test_service.cpp b/test/routing_tests/local_routing_test_service.cpp deleted file mode 100644 index 81d47eb..0000000 --- a/test/routing_tests/local_routing_test_service.cpp +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "local_routing_test_service.hpp" - -local_routing_test_service::local_routing_test_service(bool _use_static_routing) : - app_(vsomeip::runtime::get()->create_application()), - is_registered_(false), - use_static_routing_(_use_static_routing), - blocked_(false), - number_of_received_messages_(0), - offer_thread_(std::bind(&local_routing_test_service::run, this)) -{ -} - -bool local_routing_test_service::init() -{ - std::lock_guard its_lock(mutex_); - - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, - std::bind(&local_routing_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&local_routing_test_service::on_state, this, - std::placeholders::_1)); - - VSOMEIP_INFO << "Static routing " << (use_static_routing_ ? "ON" : "OFF"); - return true; -} - -void local_routing_test_service::start() -{ - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void local_routing_test_service::stop() -{ - VSOMEIP_INFO << "Stopping..."; - app_->clear_all_handler(); - app_->stop(); -} - -void local_routing_test_service::join_offer_thread() -{ - offer_thread_.join(); -} - -void local_routing_test_service::offer() -{ - app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void local_routing_test_service::stop_offer() -{ - app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void local_routing_test_service::on_state(vsomeip::state_type_e _state) -{ - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : - "deregistered."); - - if(_state == vsomeip::state_type_e::ST_REGISTERED) - { - if(!is_registered_) - { - is_registered_ = true; - std::lock_guard its_lock(mutex_); - blocked_ = true; - // "start" the run method thread - condition_.notify_one(); - } - } - else - { - is_registered_ = false; - } -} - -void local_routing_test_service::on_message(const std::shared_ptr& _request) -{ - VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _request->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _request->get_session() << "]"; - - number_of_received_messages_++; - - ASSERT_EQ(_request->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID); - ASSERT_EQ(_request->get_method(), vsomeip_test::TEST_SERVICE_METHOD_ID); - - // Check the protocol version this shall be set to 0x01 according to the spec. - // TR_SOMEIP_00052 - ASSERT_EQ(_request->get_protocol_version(), 0x01); - // Check the message type this shall be 0xx (REQUEST) according to the spec. - // TR_SOMEIP_00055 - ASSERT_EQ(_request->get_message_type(), vsomeip::message_type_e::MT_REQUEST); - - // check the session id. - ASSERT_EQ(_request->get_session(), static_cast(number_of_received_messages_)); - - - // send response - std::shared_ptr its_response = - vsomeip::runtime::get()->create_response(_request); - - app_->send(its_response); - - if(number_of_received_messages_ >= vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND) - { - std::lock_guard its_lock(mutex_); - blocked_ =true; - condition_.notify_one(); - } - ASSERT_LT(number_of_received_messages_, - vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND + 1); -} - -void local_routing_test_service::run() -{ - std::unique_lock its_lock(mutex_); - while (!blocked_) - condition_.wait(its_lock); - - blocked_ = false; - if(use_static_routing_) - { - offer(); - } - while (!blocked_) - condition_.wait(its_lock); - - std::thread t2([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 5));}); - t2.join(); - app_->stop(); -} - -TEST(someip_local_routing_test, receive_ten_messages_over_local_uds_socket) -{ - bool use_static_routing = true; - local_routing_test_service test_service(use_static_routing); - if (test_service.init()) { - test_service.start(); - test_service.join_offer_thread(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/routing_tests/local_routing_test_service.hpp b/test/routing_tests/local_routing_test_service.hpp deleted file mode 100644 index 531fdb7..0000000 --- a/test/routing_tests/local_routing_test_service.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef LOCALROUTINGTESTSERVICE_HPP_ -#define LOCALROUTINGTESTSERVICE_HPP_ -#include - -#include - -#include -#include -#include -#include - -#include "../someip_test_globals.hpp" - -class local_routing_test_service -{ -public: - local_routing_test_service(bool _use_static_routing); - bool init(); - void start(); - void stop(); - void offer(); - void stop_offer(); - void join_offer_thread(); - void on_state(vsomeip::state_type_e _state); - void on_message(const std::shared_ptr &_request); - void run(); - -private: - std::shared_ptr app_; - bool is_registered_; - bool use_static_routing_; - - bool blocked_; - std::uint32_t number_of_received_messages_; - std::mutex mutex_; - std::condition_variable condition_; - std::thread offer_thread_; -}; - -#endif /* LOCALROUTINGTESTSERVICE_HPP_ */ diff --git a/test/routing_tests/local_routing_test_service.json b/test/routing_tests/local_routing_test_service.json deleted file mode 100644 index 6b7e11d..0000000 --- a/test/routing_tests/local_routing_test_service.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "unicast" : "127.0.0.1", - "diagnosis":"0x12", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : - { - "enable" : "false", - "path" : "/tmp/vsomeip.log" - }, - - "dlt" : "false" - }, - - "applications" : - [ - { - "name" : "local_routing_test_service", - "id" : "0x1277" - } - ], - - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678" - } - ], - - "routing" : "routingmanagerd", - "service-discovery" : - { - "enable" : "false", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp" - } -} diff --git a/test/routing_tests/local_routing_test_service_start.sh b/test/routing_tests/local_routing_test_service_start.sh deleted file mode 100755 index c59364c..0000000 --- a/test/routing_tests/local_routing_test_service_start.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -export VSOMEIP_APPLICATION_NAME=local_routing_test_service -export VSOMEIP_CONFIGURATION=local_routing_test_service.json -./local_routing_test_service diff --git a/test/second_address_tests/conf/second_address_test_master_client.json.in b/test/second_address_tests/conf/second_address_test_master_client.json.in deleted file mode 100644 index 542480f..0000000 --- a/test/second_address_tests/conf/second_address_test_master_client.json.in +++ /dev/null @@ -1,32 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications" : - [ - { - "name" : "second_address_test_client", - "id" : "0x1210", - "max_dispatch_time" : "1000" - } - ], - "routing":"routingmanagerd", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.50.1", - "port":"30490", - "protocol":"udp", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/second_address_tests/conf/second_address_test_master_service_udp.json.in b/test/second_address_tests/conf/second_address_test_master_service_udp.json.in deleted file mode 100644 index 1b45898..0000000 --- a/test/second_address_tests/conf/second_address_test_master_service_udp.json.in +++ /dev/null @@ -1,40 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications" : - [ - { - "name" : "second_address_test_service", - "id" : "0x3489", - "max_dispatch_time" : "1000" - } - ], - "services": - [ - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30001" - } - ], - "routing":"routingmanagerd", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.50.1", - "port":"30490", - "protocol":"udp", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/second_address_tests/conf/second_address_test_slave_client.json.in b/test/second_address_tests/conf/second_address_test_slave_client.json.in deleted file mode 100644 index 303bfae..0000000 --- a/test/second_address_tests/conf/second_address_test_slave_client.json.in +++ /dev/null @@ -1,32 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE_SECOND@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications" : - [ - { - "name" : "second_address_test_client", - "id" : "0x1210", - "max_dispatch_time" : "1000" - } - ], - "routing":"routingmanagerd", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.50.1", - "port":"30490", - "protocol":"udp", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/second_address_tests/conf/second_address_test_slave_service_udp.json.in b/test/second_address_tests/conf/second_address_test_slave_service_udp.json.in deleted file mode 100644 index 9a7c062..0000000 --- a/test/second_address_tests/conf/second_address_test_slave_service_udp.json.in +++ /dev/null @@ -1,40 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE_SECOND@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications" : - [ - { - "name" : "second_address_test_service", - "id" : "0x3489", - "max_dispatch_time" : "1000" - } - ], - "services": - [ - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30001" - } - ], - "routing":"routingmanagerd", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.50.1", - "port":"30490", - "protocol":"udp", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/second_address_tests/conf/second_address_test_slave_starter.sh.in b/test/second_address_tests/conf/second_address_test_slave_starter.sh.in deleted file mode 100755 index 8924163..0000000 --- a/test/second_address_tests/conf/second_address_test_slave_starter.sh.in +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -FAIL=0 - -if [ $# -lt 2 ] -then - echo "Please pass a operation and communication mode to this script." - echo "For example: $0 CLIENT UDP" - echo "Valid operation modes include [SERVICE, CLIENT]" - echo "Valid communication modes include [UDP, TCP]" - exit 1 -fi - -OPERATIONMODE=$1 -COMMUNICATIONMODE=$2 - -# Add second IP address to interface -ip addr add @TEST_IP_SLAVE_SECOND@/32 dev eth0 - -if [ "$OPERATIONMODE" = "CLIENT" ]; then - SLAVE_APPLICATION=second_address_test_client - export VSOMEIP_CONFIGURATION=second_address_test_slave_client.json - -elif [ "$OPERATIONMODE" = "SERVICE" ]; then - SLAVE_APPLICATION=second_address_test_service - - if [ "$COMMUNICATIONMODE" = "TCP" ]; then - export VSOMEIP_CONFIGURATION=second_address_test_slave_service_tcp.json - elif [ "$COMMUNICATIONMODE" = "UDP" ]; then - export VSOMEIP_CONFIGURATION=second_address_test_slave_service_udp.json - fi -fi - -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -./$SLAVE_APPLICATION $COMMUNICATIONMODE & -PID_SLAVE=$! - -# Wait until all slaves are finished -for job in $PID_SLAVE -do - # Fail gets incremented if a client exits with a non-zero exit code - echo "waiting for $job" - wait $job || FAIL=$(($FAIL+1)) -done - -# kill the services -kill $PID_VSOMEIPD -sleep 1 - -# Delete second IP address -ip addr del @TEST_IP_SLAVE_SECOND@/32 dev eth0 - -# Check if everything went well -exit $FAIL diff --git a/test/second_address_tests/second_address_test_client.cpp b/test/second_address_tests/second_address_test_client.cpp deleted file mode 100644 index 616346b..0000000 --- a/test/second_address_tests/second_address_test_client.cpp +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright (C) 2014-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "second_address_test_globals.hpp" - -class second_address_test_client { -public: - second_address_test_client(struct second_address_test::service_info _service_info, bool _use_tcp) : - service_info_(_service_info), - use_tcp_(_use_tcp), - app_(vsomeip::runtime::get()->create_application("second_address_test_client")), - send_thread_(std::bind(&second_address_test_client::send, this)) { - - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - - app_->register_state_handler( - std::bind(&second_address_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.request_method_id, - std::bind(&second_address_test_client::on_message, this, - std::placeholders::_1)); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.event_id, - std::bind(&second_address_test_client::on_notification, this, - std::placeholders::_1, false)); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.selective_event_id, - std::bind(&second_address_test_client::on_notification, this, - std::placeholders::_1, true)); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.shutdown_method_id, - std::bind(&second_address_test_client::on_shutdown_method_called, this, - std::placeholders::_1)); - - // register availability for all other services and request their event. - app_->register_availability_handler(service_info_.service_id, - service_info_.instance_id, - std::bind(&second_address_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - - app_->request_service(service_info_.service_id, - service_info_.instance_id); - - app_->register_subscription_status_handler(service_info_.service_id, - service_info_.instance_id, service_info_.eventgroup_id, - service_info_.event_id, - std::bind(&second_address_test_client::on_subscription_status_changed, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4, - std::placeholders::_5, false)); - - app_->register_subscription_status_handler(service_info_.service_id, - service_info_.instance_id, service_info_.selective_eventgroup_id, - service_info_.selective_event_id, - std::bind(&second_address_test_client::on_subscription_status_changed, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4, - std::placeholders::_5, true)); - - app_->start(); - } - - ~second_address_test_client() { - send_thread_.join(); - } - - void subscribe() { - std::set its_eventgroups; - its_eventgroups.insert(service_info_.eventgroup_id); - - app_->request_event(service_info_.service_id, - service_info_.instance_id, service_info_.event_id, - its_eventgroups, vsomeip::event_type_e::ET_EVENT); - - its_eventgroups.clear(); - its_eventgroups.insert(service_info_.selective_eventgroup_id); - - app_->request_event(service_info_.service_id, - service_info_.instance_id, service_info_.selective_event_id, - its_eventgroups, vsomeip::event_type_e::ET_SELECTIVE_EVENT); - - app_->subscribe(service_info_.service_id, service_info_.instance_id, - service_info_.eventgroup_id); - - app_->subscribe(service_info_.service_id, service_info_.instance_id, - service_info_.selective_eventgroup_id); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_DEBUG << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered" : "deregistered") << " on client."; - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, - bool _is_available) { - - VSOMEIP_DEBUG << "Service [" << std::setw(4) - << std::setfill('0') << std::hex << _service << "." << _instance - << "] is " << (_is_available ? "available":"not available") << " on client."; - - if (_is_available) { - std::lock_guard its_lock(mutex_); - wait_until_service_available_ = false; - condition_.notify_one(); - } - } - - void on_message(const std::shared_ptr &_message) { - EXPECT_EQ(service_info_.service_id, _message->get_service()); - EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - EXPECT_EQ(service_info_.request_method_id, _message->get_method()); - - std::lock_guard its_lock(mutex_); - auto its_payload = _message->get_payload(); - std::uint32_t data = static_cast(its_payload->get_data()[0]); - - EXPECT_EQ(reply_received_, data); - - wait_until_reply_received_ = false; - reply_received_++; - condition_.notify_one(); - } - - void on_notification(const std::shared_ptr &_message, - bool _selective) { - EXPECT_EQ(service_info_.service_id, _message->get_service()); - EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - - static vsomeip::length_t length_last_received_msg(0); - EXPECT_GT(_message->get_payload()->get_length(), length_last_received_msg); - length_last_received_msg = _message->get_payload()->get_length(); - - if (_selective) { - EXPECT_EQ(service_info_.selective_event_id, _message->get_method()); - - if (++number_selective_events_received_ == second_address_test::number_of_events_to_send) { - std::lock_guard its_lock(mutex_); - wait_until_selective_events_received_ = false; - condition_.notify_one(); - } - } else { - EXPECT_EQ(service_info_.event_id, _message->get_method()); - - if (++number_events_received_ == second_address_test::number_of_events_to_send) { - std::lock_guard its_lock(mutex_); - wait_until_events_received_ = false; - condition_.notify_one(); - } - } - } - - void on_subscription_status_changed(const vsomeip::service_t _service, - const vsomeip::instance_t _instance, - const vsomeip::eventgroup_t _eventgroup, - const vsomeip::event_t _event, - const uint16_t error_code, - bool _selective) { - - VSOMEIP_DEBUG << "Subscription status changed on client"; - - EXPECT_EQ(service_info_.service_id, _service); - EXPECT_EQ(service_info_.instance_id, _instance); - EXPECT_TRUE((error_code == 0x0u || error_code == 0x7u)); - - if (_selective) { - EXPECT_EQ(service_info_.selective_eventgroup_id, _eventgroup); - EXPECT_EQ(service_info_.selective_event_id, _event); - - if (error_code == 0x0u) { // accepted - std::lock_guard its_lock(mutex_); - wait_until_selective_subscription_accepted_ = false; - condition_.notify_one(); - } - - } else { - EXPECT_EQ(service_info_.eventgroup_id, _eventgroup); - EXPECT_EQ(service_info_.event_id, _event); - - if (error_code == 0x0u) { // accepted - std::lock_guard its_lock(mutex_); - wait_until_subscription_accepted_ = false; - condition_.notify_one(); - } - } - } - - void on_shutdown_method_called(const std::shared_ptr &_message) { - EXPECT_EQ(service_info_.service_id, _message->get_service()); - EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - EXPECT_EQ(service_info_.shutdown_method_id, _message->get_method()); - - std::lock_guard its_lock(mutex_); - wait_until_shutdown_reply_received_ = false; - condition_.notify_one(); - } - - void send() { - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - while (wait_until_service_available_) { - condition_.wait(its_lock); - } - - auto its_message = vsomeip::runtime::get()->create_request(use_tcp_); - its_message->set_service(service_info_.service_id); - its_message->set_instance(service_info_.instance_id); - its_message->set_method(service_info_.request_method_id); - its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST); - - auto its_payload = vsomeip::runtime::get()->create_payload(); - - VSOMEIP_DEBUG << "Client sending request messages"; - - for (std::uint32_t index = 0; index < second_address_test::number_of_messages_to_send; index++) { - vsomeip::byte_t *msg_payload = reinterpret_cast(&index); - its_payload->set_data(msg_payload, sizeof(index)); - its_message->set_payload(its_payload); - app_->send(its_message); - - wait_until_reply_received_ = true; - message_sent_++; - - while (wait_until_reply_received_) { - condition_.wait(its_lock); - } - } - - VSOMEIP_DEBUG << "Client subscribing events"; - - subscribe(); - while (wait_until_subscription_accepted_ || wait_until_selective_subscription_accepted_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "Client requesting event notification"; - - its_message->set_method(service_info_.notify_method_id); - its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); - its_payload->set_data(&second_address_test::number_of_events_to_send, 1); - its_message->set_payload(its_payload); - app_->send(its_message); - - VSOMEIP_DEBUG << "Client waiting event notification"; - - while (wait_until_events_received_ || wait_until_selective_events_received_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "Client shutting down the service"; - - // shutdown service - its_message->set_method(service_info_.shutdown_method_id); - its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST); - app_->send(its_message); - - while (wait_until_shutdown_reply_received_) { - if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) { - VSOMEIP_ERROR << "Shutdown request wasn't answered in time!"; - break; - } - } - - VSOMEIP_INFO << "Client going down"; - app_->clear_all_handler(); - app_->stop(); - } - - -private: - struct second_address_test::service_info service_info_; - bool use_tcp_; - std::shared_ptr app_; - - bool wait_until_registered_ = true; - bool wait_until_service_available_ = true; - bool wait_until_subscription_accepted_ = true; - bool wait_until_selective_subscription_accepted_ = true; - bool wait_until_shutdown_reply_received_ = true; - bool wait_until_reply_received_ = true; - bool wait_until_events_received_ = true; - bool wait_until_selective_events_received_ = true; - std::mutex mutex_; - std::condition_variable condition_; - - std::thread send_thread_; - std::uint32_t message_sent_ = 0; - std::uint32_t reply_received_ = 0; - std::uint32_t number_events_received_ = 0; - std::uint32_t number_selective_events_received_ = 0; -}; - -static bool use_tcp = false; - -TEST(someip_event_test, communicate_using_second_address) -{ - second_address_test_client its_sample(second_address_test::service, use_tcp); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if (argc < 2) { - std::cerr << "Please specify a communication mode, like: " << argv[0] << " TCP" << std::endl; - std::cerr << "Valid communication modes are UDP or TCP" << std::endl; - return 1; - } - - if (std::string("TCP")== std::string(argv[1])) { - use_tcp = true; - } else if (std::string("UDP")== std::string(argv[1])) { - use_tcp = false; - } - - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/second_address_tests/second_address_test_globals.hpp b/test/second_address_tests/second_address_test_globals.hpp deleted file mode 100644 index da5db1f..0000000 --- a/test/second_address_tests/second_address_test_globals.hpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (C) 2014-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef SECOND_ADDRESS_TEST_GLOBALS_HPP_ -#define SECOND_ADDRESS_TEST_GLOBALS_HPP_ - -namespace second_address_test { - -struct service_info { - vsomeip::service_t service_id; - vsomeip::instance_t instance_id; - vsomeip::eventgroup_t eventgroup_id; - vsomeip::event_t event_id; - vsomeip::eventgroup_t selective_eventgroup_id; - vsomeip::event_t selective_event_id; - vsomeip::method_t request_method_id; - vsomeip::method_t notify_method_id; - vsomeip::method_t shutdown_method_id; -}; - -struct service_info service = { 0x3333, 0x1, 0x1, 0x8301, 0x2, 0x8302, 0x1111, 0x2222, 0x1404 }; - -static constexpr std::uint32_t number_of_messages_to_send = 150; -static constexpr std::uint8_t number_of_events_to_send = 150; -} - -#endif /* SECOND_ADDRESS_TEST_GLOBALS_HPP_ */ diff --git a/test/second_address_tests/second_address_test_master_starter.sh b/test/second_address_tests/second_address_test_master_starter.sh deleted file mode 100755 index c68c0b5..0000000 --- a/test/second_address_tests/second_address_test_master_starter.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -FAIL=0 - -if [ $# -lt 2 ] -then - echo "Please pass a operation and communication mode to this script." - echo "For example: $0 SERVICE UDP" - echo "Valid operation modes include [SERVICE, CLIENT]" - echo "Valid communication modes include [UDP, TCP]" - exit 1 -fi - -OPERATIONMODE=$1 -COMMUNICATIONMODE=$2 - -if [ "$OPERATIONMODE" = "SERVICE" ]; then - MASTER_APPLICATION=second_address_test_service - SLAVE_OPERATIONMODE="CLIENT" - - if [ "$COMMUNICATIONMODE" = "TCP" ]; then - export VSOMEIP_CONFIGURATION=second_address_test_master_service_tcp.json - elif [ "$COMMUNICATIONMODE" = "UDP" ]; then - export VSOMEIP_CONFIGURATION=second_address_test_master_service_udp.json - fi - -elif [ "$OPERATIONMODE" = "CLIENT" ]; then - MASTER_APPLICATION=second_address_test_client - SLAVE_OPERATIONMODE="SERVICE" - export VSOMEIP_CONFIGURATION=second_address_test_master_client.json -fi - -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -./$MASTER_APPLICATION $COMMUNICATIONMODE & -PID_MASTER=$! - -sleep 1 - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting offer test on slave LXC second_address_test_slave_starter.sh" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./second_address_test_slave_starter.sh $SLAVE_OPERATIONMODE $COMMUNICATIONMODE\"" & -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS; sleep 10; ./second_address_test_slave_starter.sh $SLAVE_OPERATIONMODE $COMMUNICATIONMODE" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./second_address_test_slave_starter.sh $SLAVE_OPERATIONMODE $COMMUNICATIONMODE\" >> $WS_ROOT/slave_test_output 2>&1" & - -else -cat < -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "second_address_test_globals.hpp" - -class second_address_test_service { -public: - second_address_test_service(struct second_address_test::service_info _service_info) : - service_info_(_service_info), - app_(vsomeip::runtime::get()->create_application("second_address_test_service")), - offer_thread_(std::bind(&second_address_test_service::run, this)) { - - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - - app_->register_state_handler( - std::bind(&second_address_test_service::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.request_method_id, - std::bind(&second_address_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.notify_method_id, - std::bind(&second_address_test_service::on_notify, this, - std::placeholders::_1)); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.shutdown_method_id, - std::bind(&second_address_test_service::on_shutdown_method_called, this, - std::placeholders::_1)); - - app_->register_subscription_handler(service_info_.service_id, - service_info_.instance_id, service_info_.eventgroup_id, - std::bind(&second_address_test_service::subscription_handler, - this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4)); - - app_->register_subscription_handler(service_info_.service_id, - service_info_.instance_id, service_info_.selective_eventgroup_id, - std::bind(&second_address_test_service::selective_subscription_handler, - this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4)); - - app_->start(); - } - - ~second_address_test_service() { - offer_thread_.join(); - } - - void stop() { - app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); - app_->clear_all_handler(); - app_->stop(); - } - -private: - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered" : "deregistered") << " on service."; - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_shutdown_method_called(const std::shared_ptr &_message) { - app_->send(vsomeip::runtime::get()->create_response(_message)); - - VSOMEIP_WARNING << "************************************************************"; - VSOMEIP_WARNING << "Shutdown method called on service -> going down!"; - VSOMEIP_WARNING << "************************************************************"; - - std::lock_guard its_lock(mutex_); - wait_until_shutdown_method_called_ = false; - condition_.notify_one(); - } - - void on_message(const std::shared_ptr &_message) { - EXPECT_EQ(service_info_.service_id, _message->get_service()); - EXPECT_EQ(service_info_.request_method_id, _message->get_method()); - EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - - std::shared_ptr response = vsomeip::runtime::get()->create_response(_message); - response->set_payload(_message->get_payload()); - app_->send(response); - - std::lock_guard its_lock(mutex_); - messages_received_++; - - if (messages_received_ == second_address_test::number_of_messages_to_send) { - wait_until_receive_messages_ = false; - condition_.notify_one(); - } - } - - void on_notify(const std::shared_ptr &_message) { - EXPECT_EQ(service_info_.service_id, _message->get_service()); - EXPECT_EQ(service_info_.notify_method_id, _message->get_method()); - EXPECT_EQ(service_info_.instance_id, _message->get_instance()); - - auto its_payload = _message->get_payload(); - notifications_to_send_ = its_payload->get_data()[0]; - - std::lock_guard its_lock(mutex_); - wait_until_notify_method_called_ = false; - condition_.notify_one(); - } - - void offer() { - app_->offer_service(service_info_.service_id, service_info_.instance_id); - - std::set its_eventgroups; - its_eventgroups.insert(service_info_.eventgroup_id); - - app_->offer_event(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_eventgroups, - vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); - - its_eventgroups.clear(); - its_eventgroups.insert(service_info_.selective_eventgroup_id); - - app_->offer_event(service_info_.service_id, service_info_.instance_id, - service_info_.selective_event_id, its_eventgroups, - vsomeip::event_type_e::ET_SELECTIVE_EVENT, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN); - } - - void notify() { - EXPECT_TRUE(client_subscribed_); - EXPECT_TRUE(client_subscribed_selective_); - auto its_payload = vsomeip::runtime::get()->create_payload(); - - std::uint32_t i = 0; - - for (; i < notifications_to_send_; i++) { - its_payload->set_data(std::vector(i+1, 0x55)); - app_->notify(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_payload); - } - - for (; i < 2 * notifications_to_send_; i++) { - its_payload->set_data(std::vector(i+1, 0x55)); - app_->notify_one(service_info_.service_id, service_info_.instance_id, - service_info_.selective_event_id, its_payload, client_id_); - } - } - - void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; - - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - - while (wait_until_receive_messages_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "Service waiting for notify method has been called"; - while (wait_until_notify_method_called_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "Service notifying events"; - notify(); - - while (wait_until_shutdown_method_called_) { - condition_.wait(its_lock); - } - - its_lock.unlock(); - stop(); - } - - bool subscription_handler(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) { - (void)_uid; - (void)_gid; - VSOMEIP_DEBUG << __func__ << ": client 0x" << std::hex << std::setw(4) << std::setfill('0') << _client - << ((_subscribed) ? " subscribed" : "unsubscribed") << " on service."; - client_subscribed_ = _subscribed; - return true; - } - - bool selective_subscription_handler(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) { - (void)_uid; - (void)_gid; - VSOMEIP_DEBUG << __func__ << ": client 0x" << std::hex << std::setw(4) << std::setfill('0') << _client - << ((_subscribed) ? " subscribed" : "unsubscribed") << " on service."; - client_subscribed_selective_ = _subscribed; - client_id_ = _client; - return true; - } - -private: - struct second_address_test::service_info service_info_; - std::shared_ptr app_; - - bool wait_until_registered_ = true; - bool wait_until_receive_messages_ = true; - bool wait_until_notify_method_called_ = true; - bool wait_until_shutdown_method_called_ = true; - bool client_subscribed_ = false; - bool client_subscribed_selective_ = false; - vsomeip::client_t client_id_ = 0; - std::uint32_t messages_received_ = 0; - std::uint8_t notifications_to_send_ = 0; - std::mutex mutex_; - std::condition_variable condition_; - std::thread offer_thread_; -}; - -TEST(someip_second_address_test, test_communication_with_client) -{ - second_address_test_service its_sample(second_address_test::service); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/security_tests/conf/security_test_config_client_external_allow.json.in b/test/security_tests/conf/security_test_config_client_external_allow.json.in deleted file mode 100644 index e73f3db..0000000 --- a/test/security_tests/conf/security_test_config_client_external_allow.json.in +++ /dev/null @@ -1,90 +0,0 @@ -{ - "unicast" : "@TEST_IP_MASTER@", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "info", - "console" : "true", - "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, - "dlt" : "false" - }, - "applications" : - [ - { - "name" : "client-sample", - "id" : "0x1255" - }, - { - "name" : "routingmanagerd", - "id" : "0x2222" - } - ], - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509" - }, - { - "service" : "0x111", - "instance" : "0x5678", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509" - }, - { - "service" : "0x1234", - "instance" : "0x02", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509" - } - ], - "security" : - { - "check_credentials" : "true", - "allow_remote_clients" : "true", - "policies" : - [ - { - "credentials" : { "uid" : "@TEST_UID@", "gid" : "@TEST_GID@" }, - "allow" : - { - "requests": - [ - { - "service" : "0x1234", - "instances" : - [ - { - "ids" : ["0x5678"], - "methods" : [ {"first" : "0x8421", "last" : "0x8422" }, "0x8001", "0x7777" ] - } - ] - } - ] - } - } - ] - }, - "routing" : "routingmanagerd", - "routing-credentials" : - { - "uid" : "@TEST_UID@", - "gid" : "@TEST_GID@" - }, - "service-discovery" : - { - "enable" : "true", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp", - "initial_delay_min" : "10", - "initial_delay_max" : "100", - "repetitions_base_delay" : "200", - "repetitions_max" : "3", - "ttl" : "3", - "cyclic_offer_delay" : "2000", - "request_response_delay" : "1500" - } -} diff --git a/test/security_tests/conf/security_test_config_client_external_deny.json.in b/test/security_tests/conf/security_test_config_client_external_deny.json.in deleted file mode 100644 index 1161f4f..0000000 --- a/test/security_tests/conf/security_test_config_client_external_deny.json.in +++ /dev/null @@ -1,90 +0,0 @@ -{ - "unicast" : "@TEST_IP_MASTER@", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "info", - "console" : "true", - "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, - "dlt" : "false" - }, - "applications" : - [ - { - "name" : "client-sample", - "id" : "0x1255" - }, - { - "name" : "routingmanagerd", - "id" : "0x2222" - } - ], - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509" - }, - { - "service" : "0x111", - "instance" : "0x5678", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509" - }, - { - "service" : "0x1234", - "instance" : "0x02", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509" - } - ], - "security" : - { - "check_credentials" : "true", - "allow_remote_clients" : "false", - "policies" : - [ - { - "credentials" : { "uid" : "@TEST_UID@", "gid" : "@TEST_GID@" }, - "allow" : - { - "requests": - [ - { - "service" : "0x1234", - "instances" : - [ - { - "ids" : ["0x5678"], - "methods" : [ {"first" : "0x8421", "last" : "0x8422" }, "0x8001", "0x7777" ] - } - ] - } - ] - } - } - ] - }, - "routing" : "routingmanagerd", - "routing-credentials" : - { - "uid" : "@TEST_UID@", - "gid" : "@TEST_GID@" - }, - "service-discovery" : - { - "enable" : "true", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp", - "initial_delay_min" : "10", - "initial_delay_max" : "100", - "repetitions_base_delay" : "200", - "repetitions_max" : "3", - "ttl" : "3", - "cyclic_offer_delay" : "2000", - "request_response_delay" : "1500" - } -} diff --git a/test/security_tests/conf/security_test_config_service_external_allow.json.in b/test/security_tests/conf/security_test_config_service_external_allow.json.in deleted file mode 100644 index 4d9129a..0000000 --- a/test/security_tests/conf/security_test_config_service_external_allow.json.in +++ /dev/null @@ -1,84 +0,0 @@ -{ - "unicast" : "@TEST_IP_SLAVE@", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "info", - "console" : "true", - "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, - "dlt" : "false" - }, - "applications" : - [ - { - "name" : "service-sample", - "id" : "0x1277" - }, - { - "name" : "routingmanagerd", - "id" : "0x1111" - } - ], - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509" - }, - { - "service" : "0x111", - "instance" : "0x5678", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509" - }, - { - "service" : "0x1234", - "instance" : "0x02", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509" - } - ], - "security" : - { - "check_credentials" : "true", - "allow_remote_clients" : "true", - "policies" : - [ - { - "credentials" : { "uid" : "@TEST_UID@", "gid" : "@TEST_GID@" }, - "allow" : - { - "offers": - [ - { - "service" : "0x1234", - "instance" : "0x5678" - } - ] - } - } - ] - }, - "routing" : "routingmanagerd", - "routing-credentials" : - { - "uid" : "@TEST_UID@", - "gid" : "@TEST_GID@" - }, - "service-discovery" : - { - "enable" : "true", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp", - "initial_delay_min" : "10", - "initial_delay_max" : "100", - "repetitions_base_delay" : "200", - "repetitions_max" : "3", - "ttl" : "3", - "cyclic_offer_delay" : "2000", - "request_response_delay" : "1500" - } -} diff --git a/test/security_tests/conf/security_test_config_service_external_deny.json.in b/test/security_tests/conf/security_test_config_service_external_deny.json.in deleted file mode 100644 index 769b04f..0000000 --- a/test/security_tests/conf/security_test_config_service_external_deny.json.in +++ /dev/null @@ -1,84 +0,0 @@ -{ - "unicast" : "@TEST_IP_SLAVE@", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "info", - "console" : "true", - "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, - "dlt" : "false" - }, - "applications" : - [ - { - "name" : "service-sample", - "id" : "0x1277" - }, - { - "name" : "routingmanagerd", - "id" : "0x1111" - } - ], - "services" : - [ - { - "service" : "0x1234", - "instance" : "0x5678", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509" - }, - { - "service" : "0x111", - "instance" : "0x5678", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509" - }, - { - "service" : "0x1234", - "instance" : "0x02", - "unicast" : "@TEST_IP_MASTER@", - "unreliable" : "30509" - } - ], - "security" : - { - "check_credentials" : "true", - "allow_remote_clients" : "false", - "policies" : - [ - { - "credentials" : { "uid" : "@TEST_UID@", "gid" : "@TEST_GID@" }, - "allow" : - { - "offers": - [ - { - "service" : "0x1234", - "instance" : "0x5678" - } - ] - } - } - ] - }, - "routing" : "routingmanagerd", - "routing-credentials" : - { - "uid" : "@TEST_UID@", - "gid" : "@TEST_GID@" - }, - "service-discovery" : - { - "enable" : "true", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp", - "initial_delay_min" : "10", - "initial_delay_max" : "100", - "repetitions_base_delay" : "200", - "repetitions_max" : "3", - "ttl" : "3", - "cyclic_offer_delay" : "2000", - "request_response_delay" : "1500" - } -} diff --git a/test/security_tests/conf/security_test_local_config.json.in b/test/security_tests/conf/security_test_local_config.json.in deleted file mode 100644 index 60036f8..0000000 --- a/test/security_tests/conf/security_test_local_config.json.in +++ /dev/null @@ -1,78 +0,0 @@ -{ - "unicast" : "localhost", - "logging" : - { - "level" : "info", - "console" : "true", - "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, - "dlt" : "false" - }, - "applications" : - [ - { - "name" : "service-sample", - "id" : "0x1277" - }, - { - "name" : "client-sample", - "id" : "0x1255" - }, - { - "name" : "routingmanagerd", - "id" : "0x1111" - } - ], - "security" : - { - "check_credentials" : "true", - "policies" : - [ - { - "credentials" : { "uid" : "@TEST_UID@", "gid" : "@TEST_GID@" }, - "allow" : - { - "offers": - [ - { - "service" : "0x1234", - "instance" : "0x5678" - } - ], - "requests": - [ - { - "service" : "0x1234", - "instances" : - [ - { - "ids" : ["0x5678"], - "methods" : [ {"first" : "0x8421", "last" : "0x8422" }, "0x8001", "0x7777" ] - } - ] - } - ] - } - } - ] - }, - "routing" : "routingmanagerd", - "routing-credentials" : - { - "uid" : "@TEST_UID@", - "gid" : "@TEST_GID@" - }, - "service-discovery" : - { - "enable" : "true", - "multicast" : "224.244.224.245", - "port" : "30490", - "protocol" : "udp", - "initial_delay_min" : "10", - "initial_delay_max" : "100", - "repetitions_base_delay" : "200", - "repetitions_max" : "3", - "ttl" : "3", - "cyclic_offer_delay" : "2000", - "request_response_delay" : "1500" - } -} diff --git a/test/security_tests/security_test_client.cpp b/test/security_tests/security_test_client.cpp deleted file mode 100644 index 2890e74..0000000 --- a/test/security_tests/security_test_client.cpp +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright (C) 2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include "security_test_client.hpp" - -static bool is_remote_test = false; -static bool remote_client_allowed = true; - -security_test_client::security_test_client(bool _test_external_communication, - bool _is_remote_client_allowed) - : app_(vsomeip::runtime::get()->create_application()), - is_available_(false), - sender_(std::bind(&security_test_client::run, this)), - received_responses_(0), - received_allowed_events_(0), - test_external_communication_(_test_external_communication), - is_remote_client_allowed_(_is_remote_client_allowed) { - -} - -bool security_test_client::init() { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - - app_->register_state_handler( - std::bind(&security_test_client::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, - std::bind(&security_test_client::on_message, this, - std::placeholders::_1)); - - app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - std::bind(&security_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - - app_->register_availability_handler(0x111, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - std::bind(&security_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - - app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - 0x02, - std::bind(&security_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - return true; -} - -void security_test_client::start() { - VSOMEIP_INFO << "Starting..."; - - app_->start(); -} - -void security_test_client::stop() { - VSOMEIP_INFO << "Stopping..."; - - if (is_remote_client_allowed_) { - shutdown_service(); - } - - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - - app_->clear_all_handler(); - app_->stop(); -} - -void security_test_client::on_state(vsomeip::state_type_e _state) { - if(_state == vsomeip::state_type_e::ST_REGISTERED) { - app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); - - // request not allowed service ID - app_->request_service(0x111, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); - - // request not allowed instance ID - app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, - 0x02, false); - - // request events of eventgroup 0x01 which holds events 0x8001 (allowed) and 0x8002 (denied) - std::set its_eventgroups; - its_eventgroups.insert(0x01); - app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8001), - its_eventgroups, vsomeip::event_type_e::ET_FIELD, - vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->request_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8002), - its_eventgroups, vsomeip::event_type_e::ET_FIELD, - vsomeip::reliability_type_e::RT_UNRELIABLE); - - app_->subscribe(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, 0x01, - vsomeip::DEFAULT_MAJOR, static_cast(0x8001)); - - app_->subscribe(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, 0x01, - vsomeip::DEFAULT_MAJOR, static_cast(0x8002)); - } -} - -void security_test_client::on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - - VSOMEIP_INFO << std::hex << "Client 0x" << app_->get_client() - << " : Service [" << std::setw(4) << std::setfill('0') << std::hex - << _service << "." << _instance << "] is " - << (_is_available ? "available." : "NOT available."); - - // check that only the allowed service / instance ID gets available - if (_is_available) { - EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _service); - EXPECT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _instance); - } - - if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service - && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) { - std::unique_lock its_lock(mutex_); - if(is_available_ && !_is_available) { - is_available_ = false; - } - else if(_is_available && !is_available_) { - is_available_ = true; - condition_.notify_one(); - } - } -} - -void security_test_client::on_message(const std::shared_ptr &_response) { - VSOMEIP_INFO << "Received a response from Service [" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() - << "." - << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() - << "] to Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() - << "/" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() - << "]"; - - if(_response->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _response->get_service()); - EXPECT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _response->get_instance()); - EXPECT_EQ(vsomeip_test::TEST_SERVICE_METHOD_ID, _response->get_method()); - - if (_response->get_service() == vsomeip_test::TEST_SERVICE_SERVICE_ID && - _response->get_instance() == vsomeip_test::TEST_SERVICE_INSTANCE_ID && - _response->get_method() == vsomeip_test::TEST_SERVICE_METHOD_ID) { - received_responses_++; - if (received_responses_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS) { - VSOMEIP_WARNING << std::hex << app_->get_client() - << ": Received all messages ~> going down!"; - } - } - } else if (_response->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - // check that only allowed event 0x8001 is received - EXPECT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _response->get_service()); - EXPECT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _response->get_instance()); - EXPECT_EQ(0x8001, _response->get_method()); - received_allowed_events_++; - } -} - -void security_test_client::run() { - for (uint32_t i = 0; i < vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS; ++i) { - { - std::unique_lock its_lock(mutex_); - while (!is_available_) - { - condition_.wait(its_lock); - } - } - - auto request = vsomeip::runtime::get()->create_request(false); - request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); - - // send a request which is allowed by policy -> expect answer - app_->send(request); - - // send a request with a not allowed method ID -> expect no answer - request->set_method(0x888); - app_->send(request); - - std::this_thread::sleep_for(std::chrono::milliseconds(250)); - } - - std::this_thread::sleep_for(std::chrono::milliseconds(250)); - - if (!test_external_communication_) { - EXPECT_EQ(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS, - received_responses_); - EXPECT_EQ(received_allowed_events_, (uint32_t) 0x01); - } else if (test_external_communication_ && !is_remote_client_allowed_) { - EXPECT_EQ((uint32_t)0, received_responses_); - EXPECT_EQ((uint32_t)0, received_allowed_events_); - } else if (test_external_communication_ && is_remote_client_allowed_) { - EXPECT_EQ(vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS, - received_responses_); - EXPECT_EQ(received_allowed_events_, (uint32_t) 0x01); - } - stop(); -} - -void security_test_client::join_sender_thread() -{ - if (sender_.joinable()) { - sender_.join(); - } -} - -void security_test_client::shutdown_service() { - auto request = vsomeip::runtime::get()->create_request(false); - request->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); - request->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); - request->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); - app_->send(request); -} - -TEST(someip_security_test, basic_subscribe_request_response) -{ - security_test_client test_client(is_remote_test, remote_client_allowed); - if (test_client.init()) { - test_client.start(); - test_client.join_sender_thread(); - } -} - -int main(int argc, char** argv) { - - std::string test_remote("--remote"); - std::string test_local("--local"); - std::string test_allow_remote_client("--allow"); - std::string test_deny_remote_client("--deny"); - std::string help("--help"); - - int i = 1; - while (i < argc) - { - if(test_remote == argv[i]) - { - is_remote_test = true; - } - else if(test_local == argv[i]) - { - is_remote_test = false; - } - else if(test_allow_remote_client == argv[i]) - { - remote_client_allowed = true; - } - else if(test_deny_remote_client == argv[i]) - { - remote_client_allowed = false; - } - else if(help == argv[i]) - { - VSOMEIP_INFO << "Parameters:\n" - << "--remote: Run test between two hosts\n" - << "--local: Run test locally\n" - << "--allow: test is started with a policy that allows remote messages sent by this test client to the service\n" - << "--deny: test is started with a policy that denies remote messages sent by this test client to the service\n" - << "--help: print this help"; - } - i++; - } - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/test/security_tests/security_test_client.hpp b/test/security_tests/security_test_client.hpp deleted file mode 100644 index df2acc8..0000000 --- a/test/security_tests/security_test_client.hpp +++ /dev/null @@ -1,55 +0,0 @@ - -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef SECURITY_TEST_CLIENT_HPP -#define SECURITY_TEST_CLIENT_HPP - -#include - -#include - -#include "../someip_test_globals.hpp" - -#include -#include -#include -#include - -class security_test_client { -public: - security_test_client(bool _test_external_communication, - bool _is_remote_client_allowed); - bool init(); - void start(); - void stop(); - - void on_state(vsomeip::state_type_e _state); - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available); - void on_message(const std::shared_ptr &_response); - - void run(); - void join_sender_thread(); - -private: - void shutdown_service(); - - std::shared_ptr app_; - - std::mutex mutex_; - std::condition_variable condition_; - bool is_available_; - - std::thread sender_; - - std::atomic received_responses_; - std::atomic received_allowed_events_; - - bool test_external_communication_; - bool is_remote_client_allowed_; -}; - -#endif // SECURITY_TEST_CLIENT_HPP diff --git a/test/security_tests/security_test_external_master_start.sh b/test/security_tests/security_test_external_master_start.sh deleted file mode 100755 index dc41b8c..0000000 --- a/test/security_tests/security_test_external_master_start.sh +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2018 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 2 ] -then - echo "Please pass a json file to this script and wether remote clients are allowed or not " - echo "For example: $0 security_test_config_client_external_allow.json --allow" - exit 1 -fi - -MASTER_JSON_FILE=$1 -SERVICE_JSON_FILE=${MASTER_JSON_FILE/client/service} -ALLOW_DENY=$2 - -FAIL=0 - -export VSOMEIP_CONFIGURATION=$1 -export VSOMEIP_APPLICATION_NAME=routingmanagerd -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -export VSOMEIP_CONFIGURATION=$1 -export VSOMEIP_APPLICATION_NAME=client-sample -./security_test_client --remote $2 & -PID_CLIENT=$! - - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting external security test on slave LXC" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./security_test_external_slave_start.sh $SERVICE_JSON_FILE $2\"" & -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./security_test_external_slave_start.sh $SERVICE_JSON_FILE $2" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./security_test_external_slave_start.sh $SERVICE_JSON_FILE $2\" >> $WS_ROOT/slave_test_output 2>&1" & - -else -cat <create_application()), - is_registered_(false), - blocked_(false), - number_of_received_messages_(0), - offer_thread_(std::bind(&security_test_service::run, this)) { -} - -bool security_test_service::init() { - std::lock_guard its_lock(mutex_); - - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, - std::bind(&security_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, - vsomeip_test::TEST_SERVICE_INSTANCE_ID, - vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, - std::bind(&security_test_service::on_message_shutdown, this, - std::placeholders::_1)); - - app_->register_state_handler( - std::bind(&security_test_service::on_state, this, - std::placeholders::_1)); - - // offer allowed field 0x8001 eventgroup 0x01 - std::set its_eventgroups; - its_eventgroups.insert(0x01); - - app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8001), its_eventgroups, - vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); - - // also offer field 0x8002 which is not allowed to be received by client - app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8002), its_eventgroups, - vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); - - // set value to fields - std::shared_ptr its_payload = - vsomeip::runtime::get()->create_payload(); - vsomeip::byte_t its_data[2] = {static_cast((vsomeip_test::TEST_SERVICE_SERVICE_ID & 0xFF00) >> 8), - static_cast((vsomeip_test::TEST_SERVICE_SERVICE_ID & 0xFF))}; - its_payload->set_data(its_data, 2); - - app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8001), its_payload); - - app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID, - static_cast(0x8002), its_payload); - - return true; -} - -void security_test_service::start() { - VSOMEIP_INFO << "Starting..."; - app_->start(); -} - -void security_test_service::stop() { - VSOMEIP_INFO << "Stopping..."; - app_->clear_all_handler(); - app_->stop(); -} - -void security_test_service::join_offer_thread() { - if (offer_thread_.joinable()) { - offer_thread_.join(); - } -} - -void security_test_service::offer() { - app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); - - // try to offer a not allowed instance ID 0x02 (client requesting the service should not get available) - app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, 0x02); - - // try to offer a not allowed service ID 0x111 (client requesting the service should not get available) - app_->offer_service(0x111, vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void security_test_service::stop_offer() { - app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); -} - -void security_test_service::on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : - "deregistered."); - - if(_state == vsomeip::state_type_e::ST_REGISTERED) { - if(!is_registered_) { - is_registered_ = true; - std::lock_guard its_lock(mutex_); - blocked_ = true; - // "start" the run method thread - condition_.notify_one(); - } - } - else { - is_registered_ = false; - } -} - -void security_test_service::on_message(const std::shared_ptr& _request) { - ASSERT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _request->get_service()); - ASSERT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _request->get_instance()); - - VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _request->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _request->get_session() << "] method: " << _request->get_method() ; - - // send response - std::shared_ptr its_response = - vsomeip::runtime::get()->create_response(_request); - - app_->send(its_response); - - number_of_received_messages_++; - if(number_of_received_messages_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS) { - VSOMEIP_INFO << "Received all messages!"; - } -} - -void security_test_service::on_message_shutdown( - const std::shared_ptr& _request) { - (void)_request; - VSOMEIP_INFO << "Shutdown method was called, going down now."; - stop(); -} - -void security_test_service::run() { - std::unique_lock its_lock(mutex_); - while (!blocked_) - condition_.wait(its_lock); - - offer(); - - // do not wait for the shutdown method to be called - if (is_remote_test && !remote_client_allowed) { - std::this_thread::sleep_for(std::chrono::milliseconds(250 * vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS + 10000)); - VSOMEIP_INFO << "Shutdown the service after timeout as remote client is not allowed by policy to call shutdown method!"; - stop(); - } - -} - -TEST(someip_security_test, basic_subscribe_request_response) { - security_test_service test_service; - if (test_service.init()) { - test_service.start(); - test_service.join_offer_thread(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) { - - std::string test_remote("--remote"); - std::string test_local("--local"); - std::string test_allow_remote_client("--allow"); - std::string test_deny_remote_client("--deny"); - std::string help("--help"); - - int i = 1; - while (i < argc) - { - if(test_remote == argv[i]) - { - is_remote_test = true; - } - else if(test_local == argv[i]) - { - is_remote_test = false; - } - else if(test_allow_remote_client == argv[i]) - { - remote_client_allowed = true; - } - else if(test_deny_remote_client == argv[i]) - { - remote_client_allowed = false; - } - else if(help == argv[i]) - { - VSOMEIP_INFO << "Parameters:\n" - << "--remote: Run test between two hosts\n" - << "--local: Run test locally\n" - << "--allow: test is started with a policy that allows remote messages sent by this test client to the service\n" - << "--deny: test is started with a policy that denies remote messages sent by this test client to the service\n" - << "--help: print this help"; - } - i++; - } - - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/security_tests/security_test_service.hpp b/test/security_tests/security_test_service.hpp deleted file mode 100644 index 21f1f7c..0000000 --- a/test/security_tests/security_test_service.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef SECURITY_TEST_SERVICE_HPP -#define SECURITY_TEST_SERVICE_HPP - -#include - -#include - -#include "../someip_test_globals.hpp" - -#include -#include -#include - -class security_test_service { -public: - security_test_service(); - bool init(); - void start(); - void stop(); - void offer(); - void stop_offer(); - void join_offer_thread(); - void on_state(vsomeip::state_type_e _state); - void on_message(const std::shared_ptr &_request); - void on_message_shutdown(const std::shared_ptr &_request); - void run(); - -private: - std::shared_ptr app_; - bool is_registered_; - - std::mutex mutex_; - std::condition_variable condition_; - bool blocked_; - std::uint32_t number_of_received_messages_; - std::thread offer_thread_; -}; - -#endif // SECURITY_TEST_SERVICE_HPP diff --git a/test/someip_test_globals.hpp b/test/someip_test_globals.hpp deleted file mode 100644 index 4380cd3..0000000 --- a/test/someip_test_globals.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef SOMEIP_TEST_GLOBALS_HPP_ -#define SOMEIP_TEST_GLOBALS_HPP_ - -#include -#include - -namespace vsomeip_test -{ - -// Service -constexpr vsomeip::service_t TEST_SERVICE_SERVICE_ID = 0x1234; -constexpr vsomeip::instance_t TEST_SERVICE_INSTANCE_ID = 0x5678; -constexpr vsomeip::method_t TEST_SERVICE_METHOD_ID = 0x8421; -constexpr vsomeip::method_t TEST_SERVICE_METHOD_ID_SHUTDOWN = 0x7777; -constexpr vsomeip::client_t TEST_SERVICE_CLIENT_ID = 0x1277; - -// Client local -constexpr vsomeip::client_t TEST_CLIENT_CLIENT_ID = 0x1255; - -// Client external -constexpr vsomeip::client_t TEST_CLIENT_EXTERNAL_CLIENT_ID = 0x1644; - - -constexpr std::uint32_t NUMBER_OF_MESSAGES_TO_SEND = 10; -constexpr vsomeip::session_t TEST_INITIAL_SESSION_ID = 0x1; - -constexpr std::uint32_t NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS = 1000; -constexpr vsomeip::byte_t PAYLOAD_TEST_DATA = 0xDD; -constexpr std::uint32_t MAX_PAYLOADSIZE = 1024*128; -// TR_SOMEIP_00061 -constexpr std::uint32_t MAX_PAYLOADSIZE_UDP = 1400; - -constexpr std::uint32_t NUMBER_OF_MESSAGES_TO_SEND_ROUTING_RESTART_TESTS = 32; - -constexpr std::uint32_t NUMBER_OF_MESSAGES_TO_SEND_SECURITY_TESTS = 32; -} - -#endif /* SOMEIP_TEST_GLOBALS_HPP_ */ diff --git a/test/someip_tp_tests/conf/someip_tp_test_master.json.in b/test/someip_tp_tests/conf/someip_tp_test_master.json.in deleted file mode 100644 index a2f67a1..0000000 --- a/test/someip_tp_tests/conf/someip_tp_test_master.json.in +++ /dev/null @@ -1,45 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"info", - "console":"true" - }, - "applications" : - [ - { - "name" : "someip_tp_test_service", - "id" : "0xCAFE" - } - ], - "services": - [ - { - "service":"0x4545", - "instance":"0x1", - "unreliable":"30001", - "someip-tp" : { - "service-to-client": [ "0x4545", "0x8001"] - } - }, - { - "service":"0x6767", - "instance":"0x1", - "unicast" : "@TEST_IP_SLAVE@", - "unreliable":"40001", - "someip-tp" : { - "client-to-service": [ "0x6767", "0x8001" ] - } - } - ], - "max-payload-size-unreliable" : "8352", - "routing":"routingmanagerd", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.77.1", - "port":"30490", - "protocol":"udp", - "cyclic_offer_delay" : "1000" - } -} \ No newline at end of file diff --git a/test/someip_tp_tests/conf/someip_tp_test_master_starter.sh.in b/test/someip_tp_tests/conf/someip_tp_test_master_starter.sh.in deleted file mode 100755 index 56e3ddf..0000000 --- a/test/someip_tp_tests/conf/someip_tp_test_master_starter.sh.in +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -FAIL=0 - -if [ $# -lt 1 ] -then - echo "Please pass a test mode to this script." - echo "For example: $0 IN_SEQUENCE" - echo "Valid subscription types include:" - echo " [IN_SEQUENCE, MIXED, INCOMPLETE, DUPLICATE, OVERLAP, OVERLAP_FRONT_BACK]" - exit 1 -fi -TESTMODE=$1 -export VSOMEIP_CONFIGURATION=someip_tp_test_master.json -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! -# Start the services -./someip_tp_test_service $1 & -PID_SERIVCE=$! - -sleep 1 - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "Waiting for 5s" - sleep 5 - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./someip_tp_test_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $TESTMODE\"" & - echo "remote ssh pid: $!" -elif [ ! -z "$USE_DOCKER" ]; then - echo "Waiting for 5s" - sleep 5 - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./someip_tp_test_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $TESTMODE" & -elif [ ! -z "$JENKINS" ]; then - echo "Waiting for 5s" - sleep 5 - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./someip_tp_test_msg_sender @TEST_IP_MASTER@ @TEST_IP_SLAVE@ $TESTMODE\" >> $WS_ROOT/slave_test_output 2>&1" & -else -cat < - -namespace someip_tp_test { - -struct service_info { - vsomeip::service_t service_id; - vsomeip::instance_t instance_id; - vsomeip::method_t method_id; - vsomeip::event_t event_id; - vsomeip::eventgroup_t eventgroup_id; - vsomeip::method_t shutdown_method_id; - vsomeip::method_t notify_method_id; -}; - -struct service_info service = { 0x4545, 0x1, 0x4545, 0x8001, 0x1, 0x4501, 0x4502 }; -struct service_info service_slave = { 0x6767, 0x1, 0x6767, 0x8001, 0x1, 0x6701, 0x6702 }; - -enum test_mode_e { - IN_SEQUENCE, - MIXED, - INCOMPLETE, - DUPLICATE, - OVERLAP, - OVERLAP_FRONT_BACK -}; - -const std::uint32_t number_of_fragments = 6; -const std::uint32_t max_segment_size = 1392; - -} - -#endif /* SOMEIP_TP_TEST_GLOBALS_HPP_ */ diff --git a/test/someip_tp_tests/someip_tp_test_msg_sender.cpp b/test/someip_tp_tests/someip_tp_test_msg_sender.cpp deleted file mode 100644 index c930acb..0000000 --- a/test/someip_tp_tests/someip_tp_test_msg_sender.cpp +++ /dev/null @@ -1,1387 +0,0 @@ -// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef _WIN32 -#include -#endif - -#include - -#include - -#include - -#include "../../implementation/utility/include/byteorder.hpp" -#include "../../implementation/message/include/deserializer.hpp" -#include "../../implementation/message/include/serializer.hpp" -#include "../../implementation/service_discovery/include/service_discovery.hpp" -#include "../../implementation/service_discovery/include/message_impl.hpp" -#include "../../implementation/service_discovery/include/constants.hpp" -#include "../../implementation/service_discovery/include/enumeration_types.hpp" -#include "../../implementation/service_discovery/include/eventgroupentry_impl.hpp" -#include "../../implementation/service_discovery/include/serviceentry_impl.hpp" -#include "../../implementation/message/include/message_impl.hpp" -#include "../../implementation/service_discovery/include/option_impl.hpp" -#include "../../implementation/service_discovery/include/ipv4_option_impl.hpp" -#include "../../implementation/endpoints/include/tp.hpp" -#include "../../implementation/endpoints/include/tp_reassembler.hpp" -#include "../../implementation/message/include/payload_impl.hpp" - -#include "someip_tp_test_globals.hpp" - -static char* remote_address; -static char* local_address; - -std::vector its_modes({ - someip_tp_test::test_mode_e::IN_SEQUENCE, - someip_tp_test::test_mode_e::MIXED, - someip_tp_test::test_mode_e::INCOMPLETE, - someip_tp_test::test_mode_e::DUPLICATE, - someip_tp_test::test_mode_e::OVERLAP, - someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK, -}); - -class someip_tp : public ::testing::TestWithParam { -public: - someip_tp() : - work_(std::make_shared(io_)), - io_thread_(std::bind(&someip_tp::io_run, this)), - session_(0x0), - sd_session_(0x0), - address_remote_(boost::asio::ip::address::from_string(std::string(remote_address))), - address_local_(boost::asio::ip::address::from_string(std::string(local_address))), - runtime_(vsomeip::runtime::get()) {} -protected: - void TearDown() { - work_.reset(); - io_thread_.join(); - io_.stop(); - } - - void call_shutdown_method() { - boost::system::error_code ec; - std::uint8_t shutdown_call[] = { - 0x45, 0x45, 0x45, 0x01, - 0x00, 0x00, 0x00, 0x08, - 0xDD, 0xDD, 0x00, 0x01, - 0x01, 0x00, 0x00, 0x00 }; - boost::asio::ip::udp::socket::endpoint_type target_service(address_remote_, - 30001); - boost::asio::ip::udp::socket udp_socket2(io_, boost::asio::ip::udp::v4()); - udp_socket2.send_to(boost::asio::buffer(shutdown_call), target_service); - udp_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_socket2.close(ec); - } - - void io_run() { - io_.run(); - } - - void offer_service(boost::asio::ip::udp::socket* const _udp_socket) { - // offer the service - std::uint8_t its_offer_service_message[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x30, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, // length entries array - 0x01, 0x00, 0x00, 0x20, - 0x67, 0x67, 0x00, 0x01, // service / instance - 0x00, 0xff, 0xff, 0xff, // major / ttl - 0x00, 0x00, 0x00, 0x00, // minor - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // slave address - 0x00, 0x11, 0x9c, 0x41, - }; - std::memcpy(&its_offer_service_message[48], &address_local_.to_v4().to_bytes()[0], 4); - std::uint16_t its_session = htons(++sd_session_); - std::memcpy(&its_offer_service_message[10], &its_session, sizeof(its_session)); - - boost::asio::ip::udp::socket::endpoint_type target_sd(address_remote_,30490); - _udp_socket->send_to(boost::asio::buffer(its_offer_service_message), target_sd); - } - - void subscribe_at_master(boost::asio::ip::udp::socket* const _udp_socket) { - std::uint8_t its_subscription[] = { - 0xff, 0xff, 0x81, 0x00, - 0x00, 0x00, 0x00, 0x30, // length - 0x00, 0x00, 0x00, 0x01, - 0x01, 0x01, 0x02, 0x00, - 0xc0, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x10, // length entries array - 0x06, 0x00, 0x00, 0x10, - 0x45, 0x45, 0x00, 0x01, // service / instance - 0x00, 0xff, 0xff, 0xff, // major / ttl - 0x00, 0x00, 0x00, 0x01, // counter - 0x00, 0x00, 0x00, 0x0c, // length options array - 0x00, 0x09, 0x04, 0x00, - 0xff, 0xff, 0xff, 0xff, // slave address - 0x00, 0x11, 0x75, 0x31, // port 30001 - }; - std::memcpy(&its_subscription[48], &address_local_.to_v4().to_bytes()[0], 4); - std::uint16_t its_session = htons(++sd_session_); - std::memcpy(&its_subscription[10], &its_session, sizeof(its_session)); - - boost::asio::ip::udp::socket::endpoint_type target_sd(address_remote_,30490); - _udp_socket->send_to(boost::asio::buffer(its_subscription), target_sd); - } - - /* - * @brief custom version of tp::tp_split_message with adjustable segment size - * needed to send overlapping segments within the 1392 byte segment size limit - */ - vsomeip::tp::tp_split_messages_t split_message(const std::uint8_t * const _data, - std::uint32_t _size , std::uint32_t _segment_size) { - using namespace vsomeip::tp; - using namespace vsomeip; - tp_split_messages_t split_messages; - - if (_size < VSOMEIP_MAX_UDP_MESSAGE_SIZE) { - std::cerr << __func__ << " called with size: " << std::dec << _size; - return split_messages; - } - - const auto data_end = _data + _size; - - for (auto current_offset = _data + 16; current_offset < data_end;) { - auto msg = std::make_shared(); - msg->reserve(VSOMEIP_FULL_HEADER_SIZE + sizeof(tp_header_t) + _segment_size); - // copy the header - msg->insert(msg->end(), _data, _data + VSOMEIP_FULL_HEADER_SIZE); - // change the message type - (*msg)[VSOMEIP_MESSAGE_TYPE_POS] = (*msg)[VSOMEIP_MESSAGE_TYPE_POS] | 0x20; - // check if last segment - const auto segment_end = current_offset + _segment_size; - const bool is_last_segment = (segment_end >= data_end); - // insert tp_header - const tp_header_t header = htonl( - static_cast((current_offset - VSOMEIP_FULL_HEADER_SIZE - _data)) | - static_cast((is_last_segment) ? 0x0u : 0x1u)); - - const byte_t * const headerp = reinterpret_cast(&header); - msg->insert(msg->end(), headerp, headerp + sizeof(tp_header_t)); - - // insert payload - if (is_last_segment) { - msg->insert(msg->end(), current_offset, data_end); - current_offset = data_end; - } else { - msg->insert(msg->end(), current_offset, segment_end); - current_offset += _segment_size; - } - // update length - const length_t its_length = static_cast(msg->size() - - VSOMEIP_SOMEIP_HEADER_SIZE); - *(reinterpret_cast(&(*msg)[VSOMEIP_LENGTH_POS_MIN])) = htonl(its_length); - split_messages.emplace_back(std::move(msg)); - } - - return split_messages; - } - - void create_fragments(std::uint32_t _count, vsomeip::service_t _service, - vsomeip::instance_t _instance, - vsomeip::method_t _method, - vsomeip::message_type_e _message_type, - vsomeip::client_t _client, - vsomeip::session_t _session, - std::vector* _target, - std::uint32_t _segment_size) { - vsomeip::message_impl msg; - msg.set_reliable(false); - msg.set_service(_service); - msg.set_instance(_instance); - msg.set_method(_method); - msg.set_message_type(_message_type); - msg.set_return_code(vsomeip::return_code_e::E_OK); - if (_client == vsomeip::ANY_CLIENT) { - msg.set_client(0xDDDD); - } else { - msg.set_client(_client); - } - if (_session == 0xFFFF) { - msg.set_session(++session_); - } else { - msg.set_session(_session); - } - std::vector its_payload_data; - for (uint32_t i = 0; i < _count; i++) { - its_payload_data.resize((i * _segment_size) + _segment_size, static_cast(i)); - } - std::shared_ptr payload = std::make_shared(its_payload_data); - msg.set_payload(payload); - vsomeip::serializer its_serializer(0); - msg.serialize(&its_serializer); - - *_target = split_message(its_serializer.get_data(), its_serializer.get_size(), _segment_size); - its_serializer.reset(); - - } - - vsomeip::message_buffer_t create_full_message( - const std::vector& _fragments) { - auto its_reassembler = std::make_shared( - std::numeric_limits::max(), io_); - vsomeip::message_buffer_t its_reassemlbed_msg; - for (const auto& frag : _fragments) { - const auto res = its_reassembler->process_tp_message(&(*frag)[0], - std::uint32_t(frag->size()), address_local_, 12345); - if (res.first) { - its_reassemlbed_msg = res.second; - } - } - its_reassembler->stop(); - return its_reassemlbed_msg; - } - - std::vector create_shuffled_seqeuence(std::uint32_t _count) { - std::vector its_indexes(_count); - std::iota(its_indexes.begin(), its_indexes.end(), 0); - std::random_device rd; - std::mt19937 its_twister(rd()); - std::shuffle(its_indexes.begin(), its_indexes.end(), its_twister); - return its_indexes; - } - void increase_segment_back(const vsomeip::message_buffer_ptr_t& _seg, - std::uint32_t _amount) { - _seg->resize(_seg->size() + _amount, 0xff); - // update length - *(reinterpret_cast(&((*_seg)[VSOMEIP_LENGTH_POS_MIN]))) = - htonl(static_cast(_seg->size() - VSOMEIP_SOMEIP_HEADER_SIZE)); - } - - void increase_segment_front(const vsomeip::message_buffer_ptr_t& _seg, - std::uint32_t _amount) { - // increase segment by amount - _seg->insert(_seg->begin() + VSOMEIP_TP_PAYLOAD_POS, _amount, 0xff); - - // decrease offset by amount - const vsomeip::tp::tp_header_t its_tp_header = VSOMEIP_BYTES_TO_LONG( - (*_seg)[VSOMEIP_TP_HEADER_POS_MIN], - (*_seg)[VSOMEIP_TP_HEADER_POS_MIN + 1], - (*_seg)[VSOMEIP_TP_HEADER_POS_MIN + 2], - (*_seg)[VSOMEIP_TP_HEADER_POS_MAX]); - std::uint32_t its_offset = vsomeip::tp::tp::get_offset(its_tp_header); - its_offset -= _amount; - const vsomeip::tp::tp_header_t its_new_tp_header = - htonl(static_cast(its_offset | - static_cast(its_tp_header & 0x1))); - *(reinterpret_cast( - &((*_seg)[VSOMEIP_TP_HEADER_POS_MIN]))) = its_new_tp_header; - - // update length - *(reinterpret_cast(&((*_seg)[VSOMEIP_LENGTH_POS_MIN]))) = - htonl(static_cast(_seg->size() - VSOMEIP_SOMEIP_HEADER_SIZE)); - } - - void increase_segment_front_back(const vsomeip::message_buffer_ptr_t& _seg, - std::uint32_t _amount) { - increase_segment_front(_seg, _amount); - increase_segment_back(_seg, _amount); - } - - void decrease_segment_back(const vsomeip::message_buffer_ptr_t& _seg, - std::uint32_t _amount) { - _seg->resize(_seg->size() - _amount, 0xff); - // update length - *(reinterpret_cast(&((*_seg)[VSOMEIP_LENGTH_POS_MIN]))) = - htonl(static_cast(_seg->size() - VSOMEIP_SOMEIP_HEADER_SIZE)); - } - - void decrease_segment_front(const vsomeip::message_buffer_ptr_t& _seg, - std::uint32_t _amount) { - if (_amount % 16 != 0) { - std::cerr << __func__ << ":" << __LINE__ << std::endl; - return; - } - _seg->erase(_seg->begin() + VSOMEIP_TP_PAYLOAD_POS, _seg->begin() + VSOMEIP_TP_PAYLOAD_POS + _amount); - // increase offset by amount - const vsomeip::tp::tp_header_t its_tp_header = VSOMEIP_BYTES_TO_LONG( - (*_seg)[VSOMEIP_TP_HEADER_POS_MIN], - (*_seg)[VSOMEIP_TP_HEADER_POS_MIN + 1], - (*_seg)[VSOMEIP_TP_HEADER_POS_MIN + 2], - (*_seg)[VSOMEIP_TP_HEADER_POS_MAX]); - std::uint32_t its_offset = vsomeip::tp::tp::get_offset(its_tp_header); - its_offset += _amount; - const vsomeip::tp::tp_header_t its_new_tp_header = - htonl(static_cast(its_offset | - static_cast(its_tp_header & 0x1))); - *(reinterpret_cast( - &((*_seg)[VSOMEIP_TP_HEADER_POS_MIN]))) = its_new_tp_header; - // update length - *(reinterpret_cast(&((*_seg)[VSOMEIP_LENGTH_POS_MIN]))) = - htonl(static_cast(_seg->size() - VSOMEIP_SOMEIP_HEADER_SIZE)); - } - - void decrease_segment_front_back(const vsomeip::message_buffer_ptr_t& _seg, - std::uint32_t _amount) { - if (_amount % 16 != 0) { - std::cerr << __func__ << ":" << __LINE__ << std::endl; - return; - } - decrease_segment_back(_seg, _amount); - decrease_segment_front(_seg, _amount); - } - - - enum order_e { - ASCENDING, - DESCENDING, - MIXED_PREDEFINED, - MIXED_RANDOM, - }; - - boost::asio::io_service io_; - std::shared_ptr work_; - std::thread io_thread_; - std::vector fragments_request_to_master_; - std::vector fragments_response_of_master_; - - std::vector fragments_received_as_server_; - std::vector fragments_response_to_master_; - - std::vector fragments_event_from_master_; - std::vector fragments_event_to_master_; - - std::atomic session_; - std::atomic sd_session_; - boost::asio::ip::address address_remote_; - boost::asio::ip::address address_local_; - std::shared_ptr runtime_; - someip_tp_test::test_mode_e test_mode_ = GetParam(); -}; - -INSTANTIATE_TEST_CASE_P(send_in_mode, - someip_tp, - ::testing::ValuesIn(its_modes)); - - -/* - * @test Send a big fragmented UDP request to the master and wait for the - * response. Check that the received response is the same as the request (server - * just echos the requests). - * Wait for a big fragmented UDP message request from the master and send back - * the response in the same size. Check that the request and response are - * identical. - * Do this two times one with fragments ordered ascending and one time descending. - * Wait for the master to subscribe and send back two big, fragmented - * notifications one with fragments ordered ascending and one descending - * Subscribe at master and wait for one fragmented event. - * With testmode INCOMPLETE incomplete fragments are send as well - * With testmode MIXED instead of ascending/descedning order the fragments are - * send in a predefined or in a random order - */ -TEST_P(someip_tp, send_in_mode) -{ - std::promise remote_client_subscribed; - std::atomic remote_client_subscription_port(0); - std::promise offer_received; - - std::mutex udp_sd_socket_mutex; - boost::asio::ip::udp::socket udp_sd_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30490)); - - boost::asio::ip::udp::socket udp_client_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30001)); - - boost::asio::ip::udp::socket udp_server_socket(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 40001)); - - std::thread sd_receive_thread([&](){ - std::atomic keep_receiving(true); - std::vector receive_buffer(4096); - std::vector its_received_events; - std::atomic service_offered(false); - std::atomic client_subscribed(false); - - // join the sd multicast group 224.0.77.1 - udp_sd_socket.set_option(boost::asio::ip::multicast::join_group( - boost::asio::ip::address::from_string("224.0.77.1").to_v4())); - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = udp_sd_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - ADD_FAILURE() << __func__ << " error: " << error.message(); - return; - } else { - vsomeip::deserializer its_deserializer(&receive_buffer[0], bytes_transferred, 0); - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_SERVICE_POS_MIN], - receive_buffer[VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[VSOMEIP_METHOD_POS_MIN], - receive_buffer[VSOMEIP_METHOD_POS_MAX]); - if (its_service == vsomeip::sd::service && its_method == vsomeip::sd::method) { - vsomeip::sd::message_impl sd_msg; - EXPECT_TRUE(sd_msg.deserialize(&its_deserializer)); - EXPECT_EQ(1u, sd_msg.get_entries().size()); - for (const auto& e : sd_msg.get_entries()) { - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP && !client_subscribed) { - EXPECT_TRUE(e->is_eventgroup_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP, e->get_type()); - EXPECT_EQ(1,e->get_num_options(1)); - EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); - EXPECT_EQ(someip_tp_test::service_slave.service_id, e->get_service()); - EXPECT_EQ(someip_tp_test::service_slave.instance_id, e->get_instance()); - EXPECT_EQ(1u, sd_msg.get_options().size()); - if (e->get_type() == vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_EQ(someip_tp_test::service_slave.eventgroup_id, - its_casted_entry->get_eventgroup()); - std::shared_ptr its_option = - sd_msg.get_options().at(its_casted_entry->get_options(1)[0]); - EXPECT_TRUE(its_option > 0); - if(its_option->get_type() == vsomeip::sd::option_type_e::IP4_ENDPOINT) { - std::shared_ptr its_ipv4_option = - std::dynamic_pointer_cast (its_option); - EXPECT_TRUE(its_ipv4_option > 0); - EXPECT_EQ(vsomeip::sd::layer_four_protocol_e::UDP, its_ipv4_option->get_layer_four_protocol()); - EXPECT_EQ(address_remote_, - boost::asio::ip::address( - boost::asio::ip::address_v4(its_ipv4_option->get_address()))); - remote_client_subscription_port = its_ipv4_option->get_port(); - } - std::vector its_sub_ack(&receive_buffer[0], &receive_buffer[0] + VSOMEIP_FULL_HEADER_SIZE + 8 + (sd_msg.get_entries().size() * 16)); - its_sub_ack[24] = static_cast(vsomeip::sd::entry_type_e::SUBSCRIBE_EVENTGROUP_ACK); - // fix length - const std::uint32_t its_length = htonl(static_cast(its_sub_ack.size()) - VSOMEIP_SOMEIP_HEADER_SIZE); - std::memcpy(&its_sub_ack[4], &its_length, sizeof(its_length)); - // set number of options to zero - its_sub_ack[27] = 0x0; - // update session - std::uint16_t its_session = htons(++sd_session_); - std::memcpy(&its_sub_ack[10], &its_session, sizeof(its_session)); - boost::asio::ip::udp::socket::endpoint_type target_sd(address_remote_,30490); - { - std::lock_guard its_lock(udp_sd_socket_mutex); - udp_sd_socket.send_to(boost::asio::buffer(its_sub_ack), target_sd); - } - std::cout << __LINE__ << ": master subscribed" << std::endl; - remote_client_subscribed.set_value(); - client_subscribed = true; - } - } else if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE && !service_offered) { - EXPECT_TRUE(e->is_service_entry()); - EXPECT_EQ(vsomeip::sd::entry_type_e::OFFER_SERVICE, e->get_type()); - EXPECT_EQ(1u,e->get_num_options(1)); - EXPECT_EQ(std::uint32_t(0xFFFFFF), e->get_ttl()); - EXPECT_EQ(someip_tp_test::service.service_id, e->get_service()); - EXPECT_EQ(someip_tp_test::service.instance_id, e->get_instance()); - EXPECT_EQ(1u, sd_msg.get_options().size()); - if (e->get_type() == vsomeip::sd::entry_type_e::OFFER_SERVICE) { - std::shared_ptr its_casted_entry = - std::static_pointer_cast(e); - EXPECT_EQ(0u, its_casted_entry->get_minor_version()); - } - offer_received.set_value(); - service_offered = true; - } - } - if (service_offered && client_subscribed) { - keep_receiving = false; - } - } else { - ADD_FAILURE() << " received non-sd message"; - return; - } - } - } - }); - - std::thread send_thread([&]() { - boost::system::error_code ec; - try { - - // wait until a offer was received - if (std::future_status::timeout == offer_received.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Didn't receive offer within time"; - return; - } - - { - std::lock_guard its_lock(udp_sd_socket_mutex); - subscribe_at_master(&udp_sd_socket); - } - - std::mutex all_fragments_received_mutex_; - std::condition_variable all_fragments_received_cond_; - bool wait_for_all_response_fragments_received_(true); - std::uint32_t received_responses(0); - bool wait_for_all_event_fragments_received_(true); - - std::thread udp_client_receive_thread([&]() { - bool keep_receiving(true); - std::vector receive_buffer(4096); - while (keep_receiving) { - boost::system::error_code error; - std::size_t bytes_transferred = udp_client_socket.receive( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), 0, error); - if (error) { - keep_receiving = false; - ADD_FAILURE() << __func__ << " error: " << error.message(); - return; - } else { - std::uint32_t its_pos = 0; - - while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; - std::cout << __LINE__ << ": received response " << its_message_size << std::endl; - vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); - - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); - - vsomeip::message_impl msg; - EXPECT_TRUE(msg.deserialize(&its_deserializer)); - if (msg.get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { - EXPECT_EQ(vsomeip::message_type_e::MT_RESPONSE, msg.get_message_type()); - EXPECT_EQ(someip_tp_test::service.service_id, msg.get_service()); - } else if (msg.get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - std::cout << __LINE__ << ": received event" << std::endl; - } else if (vsomeip::tp::tp::tp_flag_is_set(receive_buffer[its_pos + VSOMEIP_MESSAGE_TYPE_POS]) && - vsomeip::tp::tp::tp_flag_unset(receive_buffer[its_pos + VSOMEIP_MESSAGE_TYPE_POS]) == vsomeip::message_type_e::MT_RESPONSE) { - EXPECT_EQ(someip_tp_test::service.service_id, its_service); - EXPECT_EQ(someip_tp_test::service.method_id, its_method); - auto its_buffer = std::make_shared(&receive_buffer[its_pos], &receive_buffer[its_pos] + its_message_size); - - fragments_response_of_master_.push_back(its_buffer); - if (fragments_response_of_master_.size() == someip_tp_test::number_of_fragments) { - std::lock_guard its_lock(all_fragments_received_mutex_); - wait_for_all_response_fragments_received_ = false; - std::cout << __LINE__ << ": received all response fragments as client" << std::endl; - all_fragments_received_cond_.notify_one(); - if (++received_responses == 2 && !wait_for_all_event_fragments_received_) { - std::cout << __LINE__ << ": received all responses as client --> Finished" << std::endl; - keep_receiving = false; - } - } - } else if (vsomeip::tp::tp::tp_flag_is_set(receive_buffer[its_pos + VSOMEIP_MESSAGE_TYPE_POS]) && - vsomeip::tp::tp::tp_flag_unset(receive_buffer[its_pos + VSOMEIP_MESSAGE_TYPE_POS]) == vsomeip::message_type_e::MT_NOTIFICATION) { - std::cout << __LINE__ << ": received event fragment" << std::endl; - EXPECT_EQ(someip_tp_test::service.service_id, its_service); - EXPECT_EQ(someip_tp_test::service.event_id, its_method); - auto its_buffer = std::make_shared(&receive_buffer[its_pos], &receive_buffer[its_pos] + its_message_size); - fragments_event_from_master_.push_back(its_buffer); - if (fragments_event_from_master_.size() == someip_tp_test::number_of_fragments) { - std::lock_guard its_lock(all_fragments_received_mutex_); - wait_for_all_event_fragments_received_ = false; - std::cout << __LINE__ << ": received all event fragments as client --> Finished" << std::endl; - all_fragments_received_cond_.notify_one(); - if (received_responses == 2) { - keep_receiving = false; - } - } - - } - its_pos += its_message_size; - bytes_transferred -= its_message_size; - } - } - } - }); - - // send SOMEI-TP message fragmented into 6 parts to service: - boost::asio::ip::udp::socket::endpoint_type target_service(address_remote_, 30001); - - std::unique_lock its_lock(all_fragments_received_mutex_); - for (const order_e mode : {order_e::ASCENDING, order_e::DESCENDING}) { - create_fragments(someip_tp_test::number_of_fragments, someip_tp_test::service.service_id, - someip_tp_test::service.instance_id, - someip_tp_test::service.method_id, - vsomeip::message_type_e::MT_REQUEST, - vsomeip::ANY_CLIENT, 0xffff, - &fragments_request_to_master_, - (test_mode_ == someip_tp_test::test_mode_e::OVERLAP || - test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) ? - vsomeip::tp::tp::tp_max_segment_length_ - 160 : - vsomeip::tp::tp::tp_max_segment_length_); - if (mode == order_e::ASCENDING) { - if (test_mode_ == someip_tp_test::test_mode_e::MIXED) { - if (someip_tp_test::number_of_fragments != 6) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } else { - auto its_indexes = {4, 1, 3, 5, 2, 0}; - std::cout << __LINE__ << ": using following predefined sequence to send request to master: "; - for (auto i : its_indexes) { std::cout << i << ", "; } - std::cout << std::endl; - for (int i : its_indexes) { - udp_client_socket.send_to(boost::asio::buffer(*fragments_request_to_master_[i]), target_service); - } - } - } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { - if (someip_tp_test::number_of_fragments != 6) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - } else { - auto its_indexes = {0,1,3,5,2,4}; - std::cout << __LINE__ << ": using following predefined sequence to send request to master: "; - for (auto i : its_indexes) { std::cout << i << ", "; } - std::cout << std::endl; - // increase third segment by 16 byte at front and back - increase_segment_front_back(fragments_request_to_master_[2], 16); - increase_segment_front(fragments_request_to_master_[4], 16); - for (int i : its_indexes) { - udp_client_socket.send_to(boost::asio::buffer(*fragments_request_to_master_[i]), target_service); - } - } - } else if (test_mode_ == someip_tp_test::test_mode_e::DUPLICATE) { - if (someip_tp_test::number_of_fragments < 2) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - for (auto iter = fragments_request_to_master_.begin(); - iter != fragments_request_to_master_.end(); iter++) { - udp_client_socket.send_to(boost::asio::buffer(*(*iter)), target_service); - // send insert 2nd fragment twice - if (iter == fragments_request_to_master_.begin() + 1) { - udp_client_socket.send_to(boost::asio::buffer(*(*iter)), target_service); - } - } - } else { - if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { - if (someip_tp_test::number_of_fragments < 3) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - // send a request fragment with a different session ID first - vsomeip::message_buffer_t msg_incomplete(*fragments_request_to_master_[2]); - msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0x33; - msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0x33; - udp_client_socket.send_to(boost::asio::buffer(msg_incomplete), target_service); - // send a request from a different src port as well to test cleanup - boost::asio::ip::udp::socket udp_client_socket2(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30004)); - msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0xcc; - msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0xcc; - udp_client_socket2.send_to(boost::asio::buffer(msg_incomplete), target_service); - boost::system::error_code ec; - udp_client_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_client_socket2.close(ec); - } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { - if (someip_tp_test::number_of_fragments < 2) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - increase_segment_back(fragments_request_to_master_[1], 16); - } - for (const auto& fragment : fragments_request_to_master_) { - udp_client_socket.send_to(boost::asio::buffer(*fragment), target_service); - } - } - } else if (mode == order_e::DESCENDING) { - if (test_mode_ == someip_tp_test::test_mode_e::MIXED) { - std::vector its_indexes = create_shuffled_seqeuence(someip_tp_test::number_of_fragments); - std::cout << __LINE__ << ": using following random sequence to send request to master: "; - for (auto i : its_indexes) { std::cout << i << ", "; } - std::cout << std::endl; - for (int i : its_indexes) { - udp_client_socket.send_to(boost::asio::buffer(*fragments_request_to_master_[i]), target_service); - } - } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { - if (someip_tp_test::number_of_fragments != 6) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - } else { - auto its_indexes = {5,3,2,4,1,0}; - std::cout << __LINE__ << ": using following predefined sequence to send request to master: "; - for (auto i : its_indexes) { std::cout << i << ", "; } - std::cout << std::endl; - // increase third segment by 16 byte at front and back - increase_segment_front_back(fragments_request_to_master_[4], 16); - for (int i : its_indexes) { - udp_client_socket.send_to(boost::asio::buffer(*fragments_request_to_master_[i]), target_service); - } - } - } else if (test_mode_ == someip_tp_test::test_mode_e::DUPLICATE) { - if (someip_tp_test::number_of_fragments < 2) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - for (auto iter = fragments_request_to_master_.rbegin(); - iter != fragments_request_to_master_.rend(); iter++) { - udp_client_socket.send_to(boost::asio::buffer(*(*iter)), target_service); - // send insert 2nd last fragment twice - if (iter == fragments_request_to_master_.rbegin() + 1) { - udp_client_socket.send_to(boost::asio::buffer(*(*iter)), target_service); - } - } - } else { - if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { - if (someip_tp_test::number_of_fragments < 4) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - // send a request fragment with a different session ID first - vsomeip::message_buffer_t msg_incomplete(*fragments_request_to_master_[3]); - msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0x77; - msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0x77; - udp_client_socket.send_to(boost::asio::buffer(msg_incomplete), target_service); - - // send a request from a different src port as well to test cleanup - boost::asio::ip::udp::socket udp_client_socket2(io_, - boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 30005)); - msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0xdd; - msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0xdd; - udp_client_socket2.send_to(boost::asio::buffer(msg_incomplete), target_service); - boost::system::error_code ec; - udp_client_socket2.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_client_socket2.close(ec); - } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { - if (someip_tp_test::number_of_fragments < 5) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - // increase second last segment by 16 byte - increase_segment_back(fragments_request_to_master_[4], 16); - } - for (auto iter = fragments_request_to_master_.rbegin(); iter != fragments_request_to_master_.rend(); iter++) { - udp_client_socket.send_to(boost::asio::buffer(*(*iter)), target_service); - } - } - } - { - while (wait_for_all_response_fragments_received_) { - if (std::cv_status::timeout == - all_fragments_received_cond_.wait_for(its_lock, - std::chrono::seconds(20))) { - ADD_FAILURE() << "Didn't receive response to" - " fragmented message within time: " << std::uint32_t(mode); - return; - } else { - EXPECT_EQ(someip_tp_test::number_of_fragments, fragments_request_to_master_.size()); - // create complete message from request - if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { - if (mode == ASCENDING) { - if (someip_tp_test::number_of_fragments < 2) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - // decrease second segment by 16 byte - decrease_segment_back(fragments_request_to_master_[1], 16); - } else if (mode == DESCENDING) { - if (someip_tp_test::number_of_fragments < 5) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - // decrease fourth segment by 16 byte - decrease_segment_back(fragments_request_to_master_[4], 16); - } - } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { - // remove the additional inserted bytes which weren't accepted on - // test masterside as they were overlapping - if (mode == ASCENDING) { - decrease_segment_front_back(fragments_request_to_master_[2], 16); - decrease_segment_front(fragments_request_to_master_[4], 16); - } else { - decrease_segment_front_back(fragments_request_to_master_[4], 16); - } - } - vsomeip::message_buffer_t its_request = create_full_message(fragments_request_to_master_); - if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP || - test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { - EXPECT_EQ(VSOMEIP_FULL_HEADER_SIZE + - someip_tp_test::number_of_fragments * (someip_tp_test::max_segment_size - 160), - its_request.size()); - } else { - EXPECT_EQ(VSOMEIP_FULL_HEADER_SIZE + - someip_tp_test::number_of_fragments * someip_tp_test::max_segment_size, - its_request.size()); - } - if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP && mode == ASCENDING) { - // response contains the additional 16 bytes of 2nd fragment instead - // of beginning of the 3rd fragment - for (std::uint32_t i = 0; i < 16; i++) { - its_request[VSOMEIP_PAYLOAD_POS + 2 * (someip_tp_test::max_segment_size - 160) + i] = 0xff; - } - } - - // create complete message from response - vsomeip::message_buffer_t its_response = create_full_message(fragments_response_of_master_); - if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP || - test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { - EXPECT_EQ(VSOMEIP_FULL_HEADER_SIZE + - someip_tp_test::number_of_fragments * (someip_tp_test::max_segment_size - 160), - its_response.size()); - } else { - EXPECT_EQ(VSOMEIP_FULL_HEADER_SIZE + - someip_tp_test::number_of_fragments * someip_tp_test::max_segment_size, - its_response.size()); - } - // change message type of response to request again - its_response[VSOMEIP_MESSAGE_TYPE_POS] = static_cast(vsomeip::message_type_e::MT_REQUEST); - // request and response should now be equal - EXPECT_EQ(its_response.size(), its_request.size()); - EXPECT_EQ(its_response, its_request); - EXPECT_EQ(0, std::memcmp(static_cast(&its_response[0]), - static_cast(&its_request[0]), - its_response.size())); - fragments_response_of_master_.clear(); - } - } - wait_for_all_response_fragments_received_ = true; - } - fragments_request_to_master_.clear(); - } - - while (wait_for_all_event_fragments_received_) { - if (std::cv_status::timeout == - all_fragments_received_cond_.wait_for(its_lock, - std::chrono::seconds(20))) { - ADD_FAILURE() << "Didn't receive fragmented event from " - " master within time"; - } - } - // check if received event is correct - { - EXPECT_EQ(someip_tp_test::number_of_fragments, fragments_event_from_master_.size()); - // create complete message from event - vsomeip::message_buffer_t its_event = create_full_message(fragments_event_from_master_); - vsomeip::session_t its_event_session = - VSOMEIP_BYTES_TO_WORD(its_event[VSOMEIP_SESSION_POS_MIN], - its_event[VSOMEIP_SESSION_POS_MAX]); - - std::vector its_cmp_event_fragments; - create_fragments(someip_tp_test::number_of_fragments, - someip_tp_test::service.service_id, - someip_tp_test::service.instance_id, - someip_tp_test::service.event_id, - vsomeip::message_type_e::MT_NOTIFICATION, - 0x0, its_event_session, &its_cmp_event_fragments, - (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) ? - vsomeip::tp::tp::tp_max_segment_length_ - 160 : - vsomeip::tp::tp::tp_max_segment_length_); - vsomeip::message_buffer_t its_cmp_event = create_full_message(its_cmp_event_fragments); - EXPECT_EQ(its_cmp_event.size(), its_event.size()); - EXPECT_EQ(its_cmp_event, its_event); - EXPECT_EQ(0, std::memcmp(static_cast(&its_cmp_event[0]), - static_cast(&its_event[0]), - its_cmp_event.size())); - } - its_lock.unlock(); - udp_client_receive_thread.join(); - } catch (const std::exception& _e) { - ADD_FAILURE() << "catched exception: " << _e.what(); - } - }); - - std::mutex all_fragments_received_as_server_mutex_; - std::unique_lock all_fragments_received_as_server_lock(all_fragments_received_as_server_mutex_); - std::condition_variable all_fragments_received_as_server_cond_; - bool wait_for_all_fragments_received_as_server_(true); - std::atomic remote_client_request_port(0); - - std::thread udp_server_send_thread([&]() { - // wait until client subscribed - if (std::future_status::timeout == remote_client_subscribed.get_future().wait_for(std::chrono::seconds(10))) { - ADD_FAILURE() << "Client didn't subscribe within time"; - return; - } - - // send fragmented event to the master - boost::asio::ip::udp::socket::endpoint_type master_client(address_remote_, remote_client_subscription_port); - for (const order_e mode : {order_e::ASCENDING, order_e::DESCENDING}) { - create_fragments(someip_tp_test::number_of_fragments, - someip_tp_test::service_slave.service_id, - someip_tp_test::service_slave.instance_id, - someip_tp_test::service_slave.event_id, - vsomeip::message_type_e::MT_NOTIFICATION, - vsomeip::ANY_CLIENT, 0xffff, - &fragments_event_to_master_, - (test_mode_ == someip_tp_test::test_mode_e::OVERLAP || - test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) ? - vsomeip::tp::tp::tp_max_segment_length_ - 160 : - vsomeip::tp::tp::tp_max_segment_length_); - if (mode == order_e::ASCENDING) { - if (test_mode_ == someip_tp_test::test_mode_e::MIXED) { - if (someip_tp_test::number_of_fragments != 6) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - } else { - auto its_indexes = {2, 3, 5, 1, 4, 0}; - std::cout << __LINE__ << ": using following predefined sequence to send event to master: "; - for (auto i : its_indexes) { std::cout << i << ", "; } - std::cout << std::endl; - for (int i : its_indexes) { - udp_server_socket.send_to(boost::asio::buffer(*fragments_event_to_master_[i]), master_client); - } - } - } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { - if (someip_tp_test::number_of_fragments != 6) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - } else { - auto its_indexes = {0,2,4,5,1,3}; - std::cout << __LINE__ << ": using following predefined sequence to send event to master: "; - for (auto i : its_indexes) { std::cout << i << ", "; } - std::cout << std::endl; - // increase second segment by 16 byte at front and back - increase_segment_front_back(fragments_event_to_master_[1], 16); - increase_segment_front(fragments_event_to_master_[3], 16); - - for (int i : its_indexes) { - udp_server_socket.send_to(boost::asio::buffer(*fragments_event_to_master_[i]), master_client); - } - } - } else if (test_mode_ == someip_tp_test::test_mode_e::DUPLICATE) { - if (someip_tp_test::number_of_fragments < 2) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - for (auto iter = fragments_event_to_master_.begin(); - iter != fragments_event_to_master_.end(); iter++) { - udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); - // send insert 2nd fragment twice - if (iter == fragments_event_to_master_.begin() + 1) { - udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); - // send oversized fragment as well - increase_segment_back(*iter, 4); - udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); - decrease_segment_back(*iter, 4); - } - } - } else { - if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { - if (someip_tp_test::number_of_fragments < 3) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - // send an event fragment with a different session ID first - vsomeip::message_buffer_t msg_incomplete(*fragments_event_to_master_[2]); - msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0x44; - msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0x44; - udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); - // send a request with a different service ID as well to test cleanup - msg_incomplete[VSOMEIP_SERVICE_POS_MIN] = 0xdd; - msg_incomplete[VSOMEIP_SERVICE_POS_MAX] = 0xdd; - msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0xdd; - msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0xdd; - udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); - } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { - if (someip_tp_test::number_of_fragments < 2) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - // increase second segment by 16 byte - increase_segment_back(fragments_event_to_master_[1], 16); - - // send one oversize message as well - std::vector oversized_event; - create_fragments(someip_tp_test::number_of_fragments + 1, - someip_tp_test::service_slave.service_id, - someip_tp_test::service_slave.instance_id, - someip_tp_test::service_slave.event_id, - vsomeip::message_type_e::MT_NOTIFICATION, - vsomeip::ANY_CLIENT, 0xffff, - &oversized_event, - vsomeip::tp::tp::tp_max_segment_length_); - for (const auto& fragment : oversized_event) { - udp_server_socket.send_to(boost::asio::buffer(*fragment), master_client); - } - } - for (const auto& fragment : fragments_event_to_master_) { - udp_server_socket.send_to(boost::asio::buffer(*fragment), master_client); - } - } - } else if (mode == order_e::DESCENDING) { - if (test_mode_ == someip_tp_test::test_mode_e::MIXED) { - std::vector its_indexes = create_shuffled_seqeuence(someip_tp_test::number_of_fragments); - std::cout << __LINE__ << ": using following random sequence to send event to master: "; - for (auto i : its_indexes) { std::cout << i << ", "; } - std::cout << std::endl; - for ( int i : its_indexes) { - udp_server_socket.send_to(boost::asio::buffer(*fragments_event_to_master_[i]), master_client); - } - } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { - if (someip_tp_test::number_of_fragments != 6) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - } else { - auto its_indexes = {5,3,2,1,0,4}; - std::cout << __LINE__ << ": using following predefined sequence to send event to master: "; - for (auto i : its_indexes) { std::cout << i << ", "; } - std::cout << std::endl; - // increase second last segment by 16 byte at front and back - increase_segment_front_back(fragments_event_to_master_[4], 16); - // update length - *(reinterpret_cast(&((*fragments_event_to_master_[4])[VSOMEIP_LENGTH_POS_MIN]))) = - htonl(static_cast(fragments_event_to_master_[4]->size() - VSOMEIP_SOMEIP_HEADER_SIZE)); - for (int i : its_indexes) { - udp_server_socket.send_to(boost::asio::buffer(*fragments_event_to_master_[i]), master_client); - } - } - } else if (test_mode_ == someip_tp_test::test_mode_e::DUPLICATE) { - if (someip_tp_test::number_of_fragments < 2) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - for (auto iter = fragments_event_to_master_.rbegin(); - iter != fragments_event_to_master_.rend(); iter++) { - udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); - // send insert 2nd last fragment twice - if (iter == fragments_event_to_master_.rbegin() + 1) { - udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); - } - } - } else { - if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { - if (someip_tp_test::number_of_fragments < 4) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - // send an event fragment with a different session ID first - vsomeip::message_buffer_t msg_incomplete(*fragments_event_to_master_[3]); - msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0x55; - msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0x55; - udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); - // send a request with a different service ID as well to test cleanup - msg_incomplete[VSOMEIP_SERVICE_POS_MIN] = 0xbb; - msg_incomplete[VSOMEIP_SERVICE_POS_MAX] = 0xbb; - msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0xbb; - msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0xbb; - udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); - - } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { - if (someip_tp_test::number_of_fragments < 5) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - // increase second last segment by 16 byte - increase_segment_back(fragments_event_to_master_[4], 16); - } - for (auto iter = fragments_event_to_master_.rbegin(); iter != fragments_event_to_master_.rend(); iter++) { - udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); - } - } - } - std::cout << __LINE__ << ": send event to master " << std::uint32_t(mode) << std::endl; - } - - for (const order_e mode : {order_e::ASCENDING, order_e::DESCENDING}) { - while (wait_for_all_fragments_received_as_server_) { - if (std::cv_status::timeout == - all_fragments_received_as_server_cond_.wait_for(all_fragments_received_as_server_lock, - std::chrono::seconds(20))) { - ADD_FAILURE() << "Didn't receive request from client within time: " << std::uint32_t(mode); - return; - } else { - EXPECT_EQ(someip_tp_test::number_of_fragments, fragments_received_as_server_.size()); - // create complete message from request of client - vsomeip::message_buffer_t its_request = create_full_message(fragments_received_as_server_); - if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP || - test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { - EXPECT_EQ(VSOMEIP_FULL_HEADER_SIZE + - someip_tp_test::number_of_fragments * (someip_tp_test::max_segment_size - 160), - its_request.size()); - } else { - EXPECT_EQ(VSOMEIP_FULL_HEADER_SIZE + - someip_tp_test::number_of_fragments * someip_tp_test::max_segment_size, - its_request.size()); - } - const vsomeip::client_t its_request_client = - VSOMEIP_BYTES_TO_WORD(its_request[VSOMEIP_CLIENT_POS_MIN], - its_request[VSOMEIP_CLIENT_POS_MAX]); - const vsomeip::session_t its_request_session = - VSOMEIP_BYTES_TO_WORD(its_request[VSOMEIP_SESSION_POS_MIN], - its_request[VSOMEIP_SESSION_POS_MAX]); - create_fragments(someip_tp_test::number_of_fragments, - someip_tp_test::service_slave.service_id, - someip_tp_test::service_slave.instance_id, - someip_tp_test::service_slave.method_id, - vsomeip::message_type_e::MT_RESPONSE, - its_request_client, - its_request_session, - &fragments_response_to_master_, - (test_mode_ == someip_tp_test::test_mode_e::OVERLAP || - test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) ? - vsomeip::tp::tp::tp_max_segment_length_ - 160: - vsomeip::tp::tp::tp_max_segment_length_); - // create complete message from response - vsomeip::message_buffer_t its_response = create_full_message(fragments_response_to_master_); - // change the message type of the response to request for comparison - its_response[VSOMEIP_MESSAGE_TYPE_POS] = static_cast(vsomeip::message_type_e::MT_REQUEST); - - EXPECT_EQ(its_response.size(), its_request.size()); - EXPECT_EQ(its_response, its_request); - EXPECT_EQ(0, std::memcmp(static_cast(&its_response[0]), - static_cast(&its_request[0]), - its_response.size())); - // send back response - fragments_received_as_server_.clear(); - EXPECT_GT(remote_client_request_port, 0); - boost::asio::ip::udp::socket::endpoint_type master_client(address_remote_, remote_client_request_port); - if (mode == order_e::ASCENDING) { - if (test_mode_ == someip_tp_test::test_mode_e::MIXED) { - if (someip_tp_test::number_of_fragments != 6) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - } else { - auto its_indexes = {4,2,0,1,3,5}; - std::cout << __LINE__ << ": using following predefined sequence to send back response to master: "; - for (auto i : its_indexes) { std::cout << i << ", "; } - std::cout << std::endl; - for (int i : its_indexes) { - udp_server_socket.send_to(boost::asio::buffer(*fragments_response_to_master_[i]), master_client); - } - } - } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { - if (someip_tp_test::number_of_fragments != 6) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - } else { - auto its_indexes = {0,2,4,3,5,1}; - std::cout << __LINE__ << ": using following predefined sequence to send response to master: "; - for (auto i : its_indexes) { std::cout << i << ", "; } - std::cout << std::endl; - // increase fourth segment by 16 byte at front and back - increase_segment_front_back(fragments_response_to_master_[3], 16); - increase_segment_front(fragments_response_to_master_[1], 16); - for (int i : its_indexes) { - udp_server_socket.send_to(boost::asio::buffer(*fragments_response_to_master_[i]), master_client); - } - } - } else if (test_mode_ == someip_tp_test::test_mode_e::DUPLICATE) { - if (someip_tp_test::number_of_fragments < 2) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - for (auto iter = fragments_response_to_master_.begin(); - iter != fragments_response_to_master_.end(); iter++) { - udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); - // send 2nd fragment twice - if (iter == fragments_response_to_master_.begin() + 1) { - udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); - // send a fragment with invalid segment size as well - decrease_segment_back(*iter, 16); - increase_segment_back(*iter, 7); - udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); - increase_segment_back(*iter, 9); - } - } - } else { - if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { - if (someip_tp_test::number_of_fragments < 5) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - // send an event fragment with a different session ID first - vsomeip::message_buffer_t msg_incomplete(*fragments_response_to_master_[4]); - msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0x99; - msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0x99; - udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); - // send a request with a different service ID as well to test cleanup - msg_incomplete[VSOMEIP_SERVICE_POS_MIN] = 0xaa; - msg_incomplete[VSOMEIP_SERVICE_POS_MAX] = 0xaa; - msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0xaa; - msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0xaa; - udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); - } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { - if (someip_tp_test::number_of_fragments < 2) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - // increase second segment by 16 byte - increase_segment_back(fragments_response_to_master_[1], 16); - } - for (const auto& frag : fragments_response_to_master_) { - udp_server_socket.send_to(boost::asio::buffer(*frag), master_client); - } - } - } else if (mode == order_e::DESCENDING) { - if (test_mode_ == someip_tp_test::test_mode_e::MIXED) { - std::vector its_indexes = create_shuffled_seqeuence(someip_tp_test::number_of_fragments); - std::cout << __LINE__ << ": using following random sequence to send back response to master: "; - for (auto i : its_indexes) { std::cout << i << ", "; } - std::cout << std::endl; - for ( int i : its_indexes) { - udp_server_socket.send_to(boost::asio::buffer(*fragments_response_to_master_[i]), master_client); - } - } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) { - if (someip_tp_test::number_of_fragments != 6) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - } else { - auto its_indexes = {5,3,2,1,4,0}; - std::cout << __LINE__ << ": using following predefined sequence to send response to master: "; - for (auto i : its_indexes) { std::cout << i << ", "; } - std::cout << std::endl; - // increase fith segment by 16 byte at front and back - increase_segment_front_back(fragments_response_to_master_[4], 16); - for (int i : its_indexes) { - udp_server_socket.send_to(boost::asio::buffer(*fragments_response_to_master_[i]), master_client); - } - } - } else if (test_mode_ == someip_tp_test::test_mode_e::DUPLICATE) { - if (someip_tp_test::number_of_fragments < 2) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - for (auto iter = fragments_response_to_master_.rbegin(); - iter != fragments_response_to_master_.rend(); iter++) { - udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); - // send insert 2nd last fragment twice - if (iter == fragments_response_to_master_.rbegin() + 1) { - udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); - } - } - } else { - if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { - if (someip_tp_test::number_of_fragments < 4) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - // send an event fragment with a different session ID first - vsomeip::message_buffer_t msg_incomplete(*fragments_response_to_master_[3]); - msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0x66; - msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0x66; - udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); - // send a request with a different service ID as well to test cleanup - msg_incomplete[VSOMEIP_SERVICE_POS_MIN] = 0xef; - msg_incomplete[VSOMEIP_SERVICE_POS_MAX] = 0xef; - msg_incomplete[VSOMEIP_SESSION_POS_MIN] = 0xef; - msg_incomplete[VSOMEIP_SESSION_POS_MAX] = 0xef; - udp_server_socket.send_to(boost::asio::buffer(msg_incomplete), master_client); - } else if (test_mode_ == someip_tp_test::test_mode_e::OVERLAP) { - if (someip_tp_test::number_of_fragments < 5) { - ADD_FAILURE() << "line: " << __LINE__ << " needs adaption as number_of_fragments changed"; - return; - } - // increase second last segment by 16 byte - increase_segment_back(fragments_response_to_master_[4], 16); - } - for (auto iter = fragments_response_to_master_.rbegin(); - iter != fragments_response_to_master_.rend(); iter++) { - udp_server_socket.send_to(boost::asio::buffer(*(*iter)), master_client); - } - } - } - } - } - wait_for_all_fragments_received_as_server_ = true; - } - }); - - std::thread udp_server_receive_thread([&]() { - { - std::lock_guard its_lock(udp_sd_socket_mutex); - offer_service(&udp_sd_socket); - } - - bool keep_receiving(true); - std::vector receive_buffer(4096); - while (keep_receiving) { - boost::system::error_code error; - boost::asio::ip::udp::socket::endpoint_type its_remote_endpoint; - std::size_t bytes_transferred = udp_server_socket.receive_from( - boost::asio::buffer(receive_buffer, receive_buffer.capacity()), its_remote_endpoint, 0, error); - if (error) { - keep_receiving = false; - ADD_FAILURE() << __func__ << " error: " << error.message(); - return; - } else { - remote_client_request_port = its_remote_endpoint.port(); - std::uint32_t its_pos = 0; - while (bytes_transferred > 0) { - const std::uint32_t its_message_size = VSOMEIP_BYTES_TO_LONG( - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 1], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 2], - receive_buffer[its_pos + VSOMEIP_LENGTH_POS_MIN + 3]) + VSOMEIP_SOMEIP_HEADER_SIZE; - std::cout << __LINE__ << ": received request from master " << its_message_size << std::endl; - vsomeip::deserializer its_deserializer(&receive_buffer[its_pos], its_message_size, 0); - - vsomeip::service_t its_service = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MIN], - receive_buffer[its_pos + VSOMEIP_SERVICE_POS_MAX]); - vsomeip::method_t its_method = VSOMEIP_BYTES_TO_WORD(receive_buffer[its_pos + VSOMEIP_METHOD_POS_MIN], - receive_buffer[its_pos + VSOMEIP_METHOD_POS_MAX]); - EXPECT_EQ(someip_tp_test::service_slave.service_id, its_service); - EXPECT_EQ(someip_tp_test::service_slave.method_id, its_method); - vsomeip::message_impl msg; - EXPECT_TRUE(msg.deserialize(&its_deserializer)); - if (vsomeip::tp::tp::tp_flag_is_set(receive_buffer[its_pos + VSOMEIP_MESSAGE_TYPE_POS])) { - auto its_buffer = std::make_shared(&receive_buffer[its_pos], &receive_buffer[its_pos] + its_message_size); - - fragments_received_as_server_.push_back(its_buffer); - if (fragments_received_as_server_.size() == someip_tp_test::number_of_fragments) { - std::lock_guard its_lock(all_fragments_received_as_server_mutex_); - wait_for_all_fragments_received_as_server_ = false; - std::cout << __LINE__ << ": received all fragments as server" << std::endl; - all_fragments_received_as_server_cond_.notify_one(); - static int received_requests = 0; - if (++received_requests == 2) { - std::cout << __LINE__ << ": received all requests as server --> Finished" << std::endl; - keep_receiving = false; - } - } - } - its_pos += its_message_size; - bytes_transferred -= its_message_size; - } - } - } - }); - - send_thread.join(); - sd_receive_thread.join(); - udp_server_receive_thread.join(); - udp_server_send_thread.join(); - - if (test_mode_ == someip_tp_test::test_mode_e::INCOMPLETE) { - std::cout << "Sleeping to let cleanup for unfinished TP message " - "trigger on master side..." << std::endl; - std::this_thread::sleep_for(std::chrono::seconds(11)); - } - // shutdown the server - call_shutdown_method(); - - boost::system::error_code ec; - udp_sd_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_sd_socket.close(ec); - udp_client_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_client_socket.close(ec); - udp_server_socket.shutdown(boost::asio::socket_base::shutdown_both, ec); - udp_server_socket.close(ec); -} - -#ifndef _WIN32 -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - if(argc < 3) { - std::cerr << "Please pass an target, local IP address and test mode to this binary like: " - << argv[0] << " 10.0.3.1 10.0.3.202 TP_IN_SEQUENCE" << std::endl; - std::cerr << "Testmodes are [ IN_SEQUENCE, MIXED, INCOMPLETE, OVERLAP, OVERLAP_FRONT_BACK ]" << std::endl; - } else { - remote_address = argv[1]; - local_address = argv[2]; - std::string its_testmode = argv[3]; - if (its_testmode == std::string("IN_SEQUENCE")) { - ::testing::GTEST_FLAG(filter) = "*send_in_mode/0"; - } else if (its_testmode == std::string("MIXED")) { - ::testing::GTEST_FLAG(filter) = "*send_in_mode/1"; - } else if (its_testmode == std::string("INCOMPLETE")) { - ::testing::GTEST_FLAG(filter) = "*send_in_mode/2"; - } else if (its_testmode == std::string("DUPLICATE")) { - ::testing::GTEST_FLAG(filter) = "*send_in_mode/3"; - } else if (its_testmode == std::string("OVERLAP")) { - ::testing::GTEST_FLAG(filter) = "*send_in_mode/4"; - } else if (its_testmode == std::string("OVERLAP_FRONT_BACK")) { - ::testing::GTEST_FLAG(filter) = "*send_in_mode/5"; - } - } - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/someip_tp_tests/someip_tp_test_service.cpp b/test/someip_tp_tests/someip_tp_test_service.cpp deleted file mode 100644 index abc1af3..0000000 --- a/test/someip_tp_tests/someip_tp_test_service.cpp +++ /dev/null @@ -1,413 +0,0 @@ -// Copyright (C) 2014-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include "../../implementation/endpoints/include/tp.hpp" - -#include "someip_tp_test_globals.hpp" - -class someip_tp_test_service { -public: - someip_tp_test_service(struct someip_tp_test::service_info _service_info, someip_tp_test::test_mode_e _testmode) : - service_info_(_service_info), - testmode_(_testmode), - app_(vsomeip::runtime::get()->create_application("someip_tp_test_service")), - wait_until_registered_(true), - wait_until_shutdown_method_called_(true), - wait_for_slave_subscription_(true), - number_notifications_of_slave_(0x0), - wait_for_slave_service_available_(true), - wait_for_two_responses_of_slave_(true), - number_responses_of_slave_(0), - wait_for_two_requests_of_slave_(true), - number_requests_from_slave_(0), - wait_for_two_notifications_of_slave_(true), - offer_thread_(std::bind(&someip_tp_test_service::run, this)) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&someip_tp_test_service::on_state, this, - std::placeholders::_1)); - - // offer field - std::set its_eventgroups; - its_eventgroups.insert(_service_info.eventgroup_id); - app_->offer_event(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_eventgroups, - vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(), - false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, service_info_.shutdown_method_id, - std::bind(&someip_tp_test_service::on_shutdown_method_called, this, - std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, service_info_.notify_method_id, - std::bind(&someip_tp_test_service::on_notify_method_called, this, - std::placeholders::_1)); - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, service_info_.method_id, - std::bind(&someip_tp_test_service::on_message, this, - std::placeholders::_1)); - - app_->register_async_subscription_handler(service_info_.service_id, - 0x1, service_info_.eventgroup_id, - std::bind(&someip_tp_test_service::subscription_handler_async, - this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, - std::placeholders::_4, std::placeholders::_5)); - - // request remote service - app_->request_service(someip_tp_test::service_slave.service_id, - someip_tp_test::service_slave.instance_id); - its_eventgroups.clear(); - its_eventgroups.insert(someip_tp_test::service_slave.eventgroup_id); - app_->request_event(someip_tp_test::service_slave.service_id, - someip_tp_test::service_slave.instance_id, - someip_tp_test::service_slave.event_id, its_eventgroups, - vsomeip::event_type_e::ET_EVENT, - vsomeip::reliability_type_e::RT_UNRELIABLE); - app_->register_message_handler(someip_tp_test::service_slave.service_id, - someip_tp_test::service_slave.instance_id, - someip_tp_test::service_slave.event_id, - std::bind(&someip_tp_test_service::on_notification, this, - std::placeholders::_1)); - app_->subscribe(someip_tp_test::service_slave.service_id, - someip_tp_test::service_slave.instance_id, - someip_tp_test::service_slave.eventgroup_id, 0x0, - someip_tp_test::service_slave.event_id); - app_->register_availability_handler(someip_tp_test::service_slave.service_id, - someip_tp_test::service_slave.instance_id, - std::bind(&someip_tp_test_service::on_availability, this, - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - app_->register_message_handler( - someip_tp_test::service_slave.service_id, - someip_tp_test::service_slave.instance_id, - someip_tp_test::service_slave.method_id, - std::bind(&someip_tp_test_service::on_response_from_slave, this, - std::placeholders::_1)); - app_->start(); - } - - ~someip_tp_test_service() { - offer_thread_.join(); - } - - void offer() { - app_->offer_service(service_info_.service_id, 0x1); - } - - void stop() { - app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); - app_->clear_all_handler(); - app_->stop(); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _available) { - if (_service == someip_tp_test::service_slave.service_id && - _instance == someip_tp_test::service_slave.instance_id && - _available) { - std::lock_guard its_lock(mutex_); - wait_for_slave_service_available_ = false; - condition_.notify_one(); - VSOMEIP_INFO << "Service available Service/Instance [" - << std::setw(4) << std::setfill('0') << std::hex << _service << "/" - << std::setw(4) << std::setfill('0') << std::hex << _instance << "]"; - } - } - - void on_message(const std::shared_ptr& _message) { - VSOMEIP_INFO << "Received a message with Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex << _message->get_session() - << "] size: " << std::dec << _message->get_payload()->get_length(); - auto response = vsomeip::runtime::get()->create_response(_message); - auto payload = vsomeip::runtime::get()->create_payload(_message->get_payload()->get_data(), _message->get_payload()->get_length()); - response->set_payload(payload); - app_->send(response); - if (++number_requests_from_slave_ == 2) { - std::lock_guard its_lock(mutex_); - wait_for_two_requests_of_slave_ = false; - condition_.notify_one(); - } - } - - void on_notification(const std::shared_ptr& _message) { - VSOMEIP_INFO << "Received a notification with Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex << _message->get_session() - << "] size: " << std::dec << _message->get_payload()->get_length(); - EXPECT_EQ(someip_tp_test::service_slave.service_id, _message->get_service()); - EXPECT_EQ(someip_tp_test::service_slave.event_id, _message->get_method()); - std::vector its_cmp_data = - generate_payload(someip_tp_test::number_of_fragments, - (testmode_ == someip_tp_test::test_mode_e::OVERLAP - || testmode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) ? - someip_tp_test::max_segment_size - 160 : - someip_tp_test::max_segment_size); - - std::vector its_rcv_data(_message->get_payload()->get_data(), - _message->get_payload()->get_data() + _message->get_payload()->get_length()); - EXPECT_EQ(its_cmp_data.size(), its_rcv_data.size()); - if (testmode_ == someip_tp_test::test_mode_e::OVERLAP) { - if (number_notifications_of_slave_ == 0) { //ASCENDING with 2nd segment too big - for (std::uint32_t i = 0; i < 16; i++) { - its_cmp_data[2 * (someip_tp_test::max_segment_size - 160) + i] = 0xff; - } - } else if (number_notifications_of_slave_ == 1) { - // DESCENDING with 2nd last segment too big - // no action as successive 4 byte at end of message would - // overwrite the beginning of the last segment which was received first - } - } - EXPECT_EQ(its_cmp_data, its_rcv_data); - EXPECT_EQ(0, std::memcmp(static_cast(&its_cmp_data[0]), - static_cast(&its_rcv_data[0]), - its_cmp_data.size())); - if (++number_notifications_of_slave_ == 2) { - std::lock_guard its_lock(mutex_); - wait_for_two_notifications_of_slave_ = false; - condition_.notify_one(); - } - } - - void on_shutdown_method_called(const std::shared_ptr &_message) { - app_->send(vsomeip::runtime::get()->create_response(_message)); - VSOMEIP_WARNING << "************************************************************"; - VSOMEIP_WARNING << "Shutdown method called -> going down!"; - VSOMEIP_WARNING << "************************************************************"; - std::lock_guard its_lock(mutex_); - wait_until_shutdown_method_called_ = false; - condition_.notify_one(); - } - - void on_notify_method_called(const std::shared_ptr &_message) { - (void)_message; - std::vector its_data = generate_payload(someip_tp_test::number_of_fragments, - (testmode_ == someip_tp_test::test_mode_e::OVERLAP) ? - someip_tp_test::max_segment_size - 160 : - someip_tp_test::max_segment_size); - std::shared_ptr its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data(its_data); - app_->notify(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_payload); - VSOMEIP_INFO << __func__ << " send event"; - notify_method_called_.set_value(true); - } - - void send_fragmented_request_to_slave() { - auto its_req = vsomeip::runtime::get()->create_request(); - its_req->set_service(someip_tp_test::service_slave.service_id); - its_req->set_instance(someip_tp_test::service_slave.instance_id); - its_req->set_method(someip_tp_test::service_slave.method_id); - std::vector its_data = generate_payload(someip_tp_test::number_of_fragments, - (testmode_ == someip_tp_test::test_mode_e::OVERLAP - || testmode_ == someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK) ? - someip_tp_test::max_segment_size - 160 : - someip_tp_test::max_segment_size); - auto its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data(its_data); - its_req->set_payload(its_payload); - request_send_to_slave_ = its_req; - app_->send(its_req); - } - - void on_response_from_slave(const std::shared_ptr &_message) { - VSOMEIP_INFO << "Received a response from the slave with Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex << _message->get_session() - << "] size: " << std::dec << _message->get_payload()->get_length(); - EXPECT_EQ(someip_tp_test::service_slave.service_id, _message->get_service()); - EXPECT_EQ(someip_tp_test::service_slave.instance_id, _message->get_instance()); - EXPECT_EQ(someip_tp_test::service_slave.method_id, _message->get_method()); - std::vector its_resp_payload(_message->get_payload()->get_data(), - _message->get_payload()->get_data() + _message->get_payload()->get_length()); - std::vector its_req_payload(request_send_to_slave_->get_payload()->get_data(), - request_send_to_slave_->get_payload()->get_data() + request_send_to_slave_->get_payload()->get_length()); - if (testmode_ == someip_tp_test::test_mode_e::OVERLAP) { - if (number_responses_of_slave_ == 0) { //ASCENDING with 2nd segment too big - for (std::uint32_t i = 0; i < 16; i++) { - its_req_payload[2 * (someip_tp_test::max_segment_size - 160) + i] = 0xff; - } - } else if (number_responses_of_slave_ == 1) { - // DESCENDING with 2nd last segment too big - // no action as successive 4 byte at end of message would - // overwrite the beginning of the last segment which was received first - } - } - - EXPECT_EQ(its_req_payload.size(), its_resp_payload.size()); - EXPECT_EQ(its_req_payload, its_resp_payload); - EXPECT_EQ(0, std::memcmp(static_cast(&its_req_payload[0]), - static_cast(&its_resp_payload[0]), - its_req_payload.size())); - - if (++number_responses_of_slave_ < 2) { - send_fragmented_request_to_slave(); - } else { - std::lock_guard its_lock(mutex_); - wait_for_two_responses_of_slave_ = false; - condition_.notify_one(); - } - } - - std::vector generate_payload(std::uint32_t _number_of_fragments, - std::uint32_t _segment_size) { - std::vector its_data; - for (std::uint32_t i = 0; i < _number_of_fragments; i++) { - its_data.resize((i * _segment_size) + _segment_size, - static_cast(i)); - } - return its_data; - } - - void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - - while (wait_for_slave_service_available_) { - condition_.wait(its_lock); - } - send_fragmented_request_to_slave(); - - while (wait_for_two_responses_of_slave_) { - condition_.wait(its_lock); - } - EXPECT_EQ(2u, number_responses_of_slave_); - - while (wait_for_two_requests_of_slave_) { - condition_.wait(its_lock); - } - EXPECT_EQ(2u, number_requests_from_slave_); - - while (wait_for_two_notifications_of_slave_) { - condition_.wait(its_lock); - } - EXPECT_EQ(2u, number_notifications_of_slave_); - - while (wait_for_slave_subscription_) { - condition_.wait(its_lock); - } - // slave subscribed --> sent a notification - on_notify_method_called(vsomeip::runtime::get()->create_message()); - - while (wait_until_shutdown_method_called_) { - condition_.wait(its_lock); - } - stop(); - } - - void subscription_handler_async(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, - bool _subscribed, const std::function& _cbk) { - (void)_uid; - (void)_gid; - VSOMEIP_WARNING << __func__ << " " << std::hex << _client << " subscribed." << _subscribed; - static int was_called = 0; - was_called++; - EXPECT_EQ(1, was_called); - EXPECT_TRUE(_subscribed); - _cbk(true); - std::lock_guard its_lock(mutex_); - wait_for_slave_subscription_ = false; - condition_.notify_one(); - } - - -private: - struct someip_tp_test::service_info service_info_; - someip_tp_test::test_mode_e testmode_; - std::shared_ptr app_; - - bool wait_until_registered_; - bool wait_until_shutdown_method_called_; - std::mutex mutex_; - std::condition_variable condition_; - std::atomic wait_for_slave_subscription_; - std::atomic number_notifications_of_slave_; - std::promise notify_method_called_; - bool wait_for_slave_service_available_; - bool wait_for_two_responses_of_slave_; - std::uint32_t number_responses_of_slave_; - bool wait_for_two_requests_of_slave_; - std::uint32_t number_requests_from_slave_; - bool wait_for_two_notifications_of_slave_; - std::shared_ptr request_send_to_slave_; - std::thread offer_thread_; -}; - -someip_tp_test::test_mode_e its_testmode(someip_tp_test::test_mode_e::IN_SEQUENCE); - -TEST(someip_someip_tp_test, echo_requests) -{ - someip_tp_test_service its_sample(someip_tp_test::service, its_testmode); -} - - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if (argc < 2) { - std::cerr << "Please pass a test mode to this binary like: " - << argv[0] << " IN_SEQUENCE" << std::endl; - std::cerr << "Testmodes are [ IN_SEQUENCE, MIXED, INCOMPLETE, DUPLICATE, OVERLAP, OVERLAP_FRONT_BACK ]" << std::endl; - exit(1); - } - - std::string its_pased_testmode = argv[1]; - if (its_pased_testmode == std::string("IN_SEQUENCE")) { - its_testmode = someip_tp_test::test_mode_e::IN_SEQUENCE; - } else if (its_pased_testmode == std::string("MIXED")) { - its_testmode = someip_tp_test::test_mode_e::MIXED; - } else if (its_pased_testmode == std::string("INCOMPLETE")) { - its_testmode = someip_tp_test::test_mode_e::INCOMPLETE; - } else if (its_pased_testmode == std::string("DUPLICATE")) { - its_testmode = someip_tp_test::test_mode_e::DUPLICATE; - } else if (its_pased_testmode == std::string("OVERLAP")) { - its_testmode = someip_tp_test::test_mode_e::OVERLAP; - } else if (its_pased_testmode == std::string("OVERLAP_FRONT_BACK")) { - its_testmode = someip_tp_test::test_mode_e::OVERLAP_FRONT_BACK; - } - - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master.json.in b/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master.json.in deleted file mode 100644 index 26d9644..0000000 --- a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master.json.in +++ /dev/null @@ -1,104 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_one_test_service_one", - "id":"0x1111" - }, - { - "name":"subscribe_notify_one_test_service_two", - "id":"0x2222" - }, - { - "name":"subscribe_notify_one_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30001", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - }, - "events" : - [ - { - "event" : "0x1111", - "is_field" : "false", - "is_reliable" : "true" - } - ] - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30002", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - }, - "events" : - [ - { - "event" : "0x2222", - "is_field" : "false", - "is_reliable" : "true" - } - ] - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30003", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - }, - "events" : - [ - { - "event" : "0x3333", - "is_field" : "false", - "is_reliable" : "true" - } - ] - } - ], - "routing":"subscribe_notify_one_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - }, - "supports_selective_broadcasts" : - { - "address" : "@TEST_IP_SLAVE@" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in b/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in deleted file mode 100644 index 7b4b606..0000000 --- a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in +++ /dev/null @@ -1,77 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_one_test_service_one", - "id":"0x1111" - }, - { - "name":"subscribe_notify_one_test_service_two", - "id":"0x2222" - }, - { - "name":"subscribe_notify_one_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_one_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - }, - "supports_selective_broadcasts" : - { - "address" : "@TEST_IP_SLAVE@" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json.in b/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json.in deleted file mode 100644 index e5218b3..0000000 --- a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json.in +++ /dev/null @@ -1,65 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_one_test_service_one", - "id":"0x1111" - }, - { - "name":"subscribe_notify_one_test_service_two", - "id":"0x2222" - }, - { - "name":"subscribe_notify_one_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30001" - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30002" - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30003" - } - ], - "routing":"subscribe_notify_one_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - }, - "supports_selective_broadcasts" : - { - "address" : "@TEST_IP_SLAVE@" - } -} diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json.in b/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json.in deleted file mode 100644 index a4283b9..0000000 --- a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave.json.in +++ /dev/null @@ -1,104 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_one_test_service_four", - "id":"0x4444" - }, - { - "name":"subscribe_notify_one_test_service_five", - "id":"0x5555" - }, - { - "name":"subscribe_notify_one_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30004", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - }, - "events" : - [ - { - "event" : "0x4444", - "is_field" : "false", - "is_reliable" : "true" - } - ] - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30005", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - }, - "events" : - [ - { - "event" : "0x5555", - "is_field" : "false", - "is_reliable" : "true" - } - ] - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30006", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - }, - "events" : - [ - { - "event" : "0x6666", - "is_field" : "false", - "is_reliable" : "true" - } - ] - } - ], - "routing":"subscribe_notify_one_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - }, - "supports_selective_broadcasts" : - { - "address" : "@TEST_IP_MASTER@" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in b/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in deleted file mode 100644 index 1cb1feb..0000000 --- a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in +++ /dev/null @@ -1,77 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_one_test_service_four", - "id":"0x4444" - }, - { - "name":"subscribe_notify_one_test_service_five", - "id":"0x5555" - }, - { - "name":"subscribe_notify_one_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_one_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - }, - "supports_selective_broadcasts" : - { - "address" : "@TEST_IP_MASTER@" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json.in b/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json.in deleted file mode 100644 index 138afae..0000000 --- a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json.in +++ /dev/null @@ -1,65 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_one_test_service_four", - "id":"0x4444" - }, - { - "name":"subscribe_notify_one_test_service_five", - "id":"0x5555" - }, - { - "name":"subscribe_notify_one_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30004" - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30005" - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30006" - } - ], - "routing":"subscribe_notify_one_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - }, - "supports_selective_broadcasts" : - { - "address" : "@TEST_IP_MASTER@" - } -} diff --git a/test/subscribe_notify_one_tests/subscribe_notify_one_test_globals.hpp b/test/subscribe_notify_one_tests/subscribe_notify_one_test_globals.hpp deleted file mode 100644 index 047ded7..0000000 --- a/test/subscribe_notify_one_tests/subscribe_notify_one_test_globals.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ -#define SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ - -namespace subscribe_notify_one_test { - -struct service_info { - vsomeip::service_t service_id; - vsomeip::instance_t instance_id; - vsomeip::method_t method_id; - vsomeip::event_t event_id; - vsomeip::eventgroup_t eventgroup_id; -}; - -static constexpr std::array service_infos = {{ - // placeholder to be consistent w/ client ids, service ids, app names - { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }, - // node 1 - { 0x1111, 0x1, 0x1111, 0x1111, 0x1000 }, - { 0x2222, 0x1, 0x2222, 0x2222, 0x2000 }, - { 0x3333, 0x1, 0x3333, 0x3333, 0x3000 }, - // node 2 - { 0x4444, 0x1, 0x4444, 0x4444, 0x4000 }, - { 0x5555, 0x1, 0x5555, 0x5555, 0x5000 }, - { 0x6666, 0x1, 0x6666, 0x6666, 0x6000 } -}}; - -static constexpr int notifications_to_send = 10; -} - -#endif /* SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ */ diff --git a/test/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh b/test/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh deleted file mode 100755 index a53104f..0000000 --- a/test/subscribe_notify_one_tests/subscribe_notify_one_test_master_starter.sh +++ /dev/null @@ -1,82 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 2 ] -then - echo "Please pass a json file and event reliability type to this script." - echo "For example: $0 subscribe_notify_one_test_diff_client_ids_diff_ports_master_udp.json UDP" - exit 1 -fi - -# replace master with slave to be able display the correct json file to be used -# with the slave script -RELIABILITY_TYPE=$1 -MASTER_JSON_FILE=$2 -CLIENT_JSON_FILE=${MASTER_JSON_FILE/master/slave} - -FAIL=0 - -# Start the services -export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_one -export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE -./subscribe_notify_one_test_service 1 $RELIABILITY_TYPE & - -export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_two -export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE -./subscribe_notify_one_test_service 2 $RELIABILITY_TYPE & - -export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_three -export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE -./subscribe_notify_one_test_service 3 $RELIABILITY_TYPE & - -sleep 3 - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting subscribe_notify_one_test_slave_starter.sh on slave LXC with parameters $CLIENT_JSON_FILE" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./subscribe_notify_one_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE\"" & - echo "remote ssh job id: $!" -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./subscribe_notify_one_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./subscribe_notify_one_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE\" >> $WS_ROOT/slave_test_output 2>&1" & - -else - cat < -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "subscribe_notify_one_test_globals.hpp" - - -class subscribe_notify_one_test_service { -public: - subscribe_notify_one_test_service(struct subscribe_notify_one_test::service_info _service_info, vsomeip::reliability_type_e _reliability_type) : - service_info_(_service_info), - app_(vsomeip::runtime::get()->create_application()), - wait_until_registered_(true), - wait_until_other_services_available_(true), - wait_until_notified_from_other_services_(true), - offer_thread_(std::bind(&subscribe_notify_one_test_service::run, this)), - wait_for_stop_(true), - stop_thread_(std::bind(&subscribe_notify_one_test_service::wait_for_stop, this)), - wait_for_notify_(true), - notify_thread_(std::bind(&subscribe_notify_one_test_service::notify_one, this)), - subscription_state_handler_called_(0), - subscription_error_occured_(false), - reliability_type_(_reliability_type) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - app_->register_state_handler( - std::bind(&subscribe_notify_one_test_service::on_state, this, - std::placeholders::_1)); - - // offer event - std::set its_eventgroups; - its_eventgroups.insert(service_info_.eventgroup_id); - app_->offer_event(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_eventgroups, vsomeip::event_type_e::ET_SELECTIVE_EVENT, - std::chrono::milliseconds::zero(), false, true, nullptr, - reliability_type_); - - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.method_id, - std::bind(&subscribe_notify_one_test_service::on_request, this, - std::placeholders::_1)); - - // register subscription handler to detect whether or not all other - // other services have subscribed - app_->register_subscription_handler(service_info_.service_id, - service_info_.instance_id, service_info_.eventgroup_id, - std::bind(&subscribe_notify_one_test_service::on_subscription, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4)); - - // register availability for all other services and request their event. - for(const auto& i : subscribe_notify_one_test::service_infos) { - if ((i.service_id == service_info_.service_id - && i.instance_id == service_info_.instance_id) - || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { - continue; - } - app_->register_message_handler(i.service_id, - i.instance_id, vsomeip::ANY_METHOD, - std::bind(&subscribe_notify_one_test_service::on_message, this, - std::placeholders::_1)); - app_->register_availability_handler(i.service_id, i.instance_id, - std::bind(&subscribe_notify_one_test_service::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - - app_->request_service(i.service_id, i.instance_id, vsomeip::DEFAULT_MAJOR, vsomeip::DEFAULT_MINOR); - - auto handler = std::bind(&subscribe_notify_one_test_service::on_subscription_state_change, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4, std::placeholders::_5); - app_->register_subscription_status_handler(i.service_id, i.instance_id, i.eventgroup_id, vsomeip::ANY_EVENT, handler); - app_->register_subscription_status_handler(vsomeip::ANY_SERVICE, i.instance_id, i.eventgroup_id, vsomeip::ANY_EVENT, handler); - app_->register_subscription_status_handler(i.service_id, vsomeip::ANY_INSTANCE, i.eventgroup_id, vsomeip::ANY_EVENT, handler); - app_->register_subscription_status_handler(vsomeip::ANY_SERVICE, vsomeip::ANY_INSTANCE, i.eventgroup_id, vsomeip::ANY_EVENT, handler); - - std::set its_eventgroups; - its_eventgroups.insert(i.eventgroup_id); - app_->request_event(i.service_id, i.instance_id, i.event_id, its_eventgroups, vsomeip::event_type_e::ET_SELECTIVE_EVENT, reliability_type_); - - other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; - other_services_received_notification_[std::make_pair(i.service_id, i.method_id)] = 0; - } - - app_->start(); - } - - ~subscribe_notify_one_test_service() { - offer_thread_.join(); - stop_thread_.join(); - } - - void offer() { - app_->offer_service(service_info_.service_id, service_info_.instance_id); - } - - void stop_offer() { - app_->stop_offer_event(service_info_.service_id, service_info_.instance_id, service_info_.event_id); - app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_DEBUG << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - if(_is_available) { - auto its_service = other_services_available_.find(std::make_pair(_service, _instance)); - if(its_service != other_services_available_.end()) { - if(its_service->second != _is_available) { - its_service->second = true; - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Service [" - << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance - << "] is available."; - - } - } - - if(std::all_of(other_services_available_.cbegin(), - other_services_available_.cend(), - [](const std::map, bool>::value_type& v) { - return v.second;})) { - std::lock_guard its_lock(mutex_); - wait_until_other_services_available_ = false; - condition_.notify_one(); - } - } - } - - void on_subscription_state_change(const vsomeip::service_t _service, const vsomeip::instance_t _instance, - const vsomeip::eventgroup_t _eventgroup, const vsomeip::event_t _event, const uint16_t _error) { - (void)_service; - (void)_instance; - (void)_eventgroup; - (void)_event; - if (!_error) { - subscription_state_handler_called_++; - } else { - subscription_error_occured_ = true; - VSOMEIP_ERROR << std::hex << app_->get_client() - << " : on_subscription_state_change: for service " << std::hex - << _service << " received a subscription error!"; - } - - } - - bool on_subscription(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) { - (void)_uid; - (void)_gid; - std::lock_guard its_subscribers_lock(subscribers_mutex_); - - // check if all other services have subscribed: - // -1 for placeholder in array and -1 for the service itself - if (subscribers_.size() == subscribe_notify_one_test::service_infos.size() - 2) { - return true; - } - - if (_subscribed) { - subscribers_.insert(_client); - } else { - subscribers_.erase(_client); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] " << "Client: " << _client - << " subscribed, now have " << std::dec << subscribers_.size() - << " subscribers. Expecting " << std::dec - << subscribe_notify_one_test::service_infos.size() - 2; - - if (subscribers_.size() == subscribe_notify_one_test::service_infos.size() - 2) - { - // notify the notify thread to start sending out notifications - std::lock_guard its_lock(notify_mutex_); - wait_for_notify_ = false; - notify_condition_.notify_one(); - } - return true; - } - - void on_request(const std::shared_ptr &_message) { - if(_message->get_message_type() == vsomeip::message_type_e::MT_REQUEST) { - VSOMEIP_DEBUG << "Received a request with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_session() << "]"; - std::shared_ptr its_response = vsomeip::runtime::get() - ->create_response(_message); - app_->send(its_response); - } - } - - void on_message(const std::shared_ptr &_message) { - if (_message->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - - other_services_received_notification_[std::make_pair(_message->get_service(), - _message->get_method())]++; - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] " - << "Received a notification with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_session() << "] from Service/Method [" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_service() << "/" << std::setw(4) << std::setfill('0') - << std::hex << _message->get_method() <<"] (now have: " - << std::dec << other_services_received_notification_[std::make_pair(_message->get_service(), - _message->get_method())] << ")"; - - if (all_notifications_received()) { - std::lock_guard its_lock(stop_mutex_); - wait_for_stop_ = false; - stop_condition_.notify_one(); - } - } - } - - bool all_notifications_received() { - return std::all_of( - other_services_received_notification_.cbegin(), - other_services_received_notification_.cend(), - [&](const std::map, std::uint32_t>::value_type& v) - { - return v.second == subscribe_notify_one_test::notifications_to_send; - } - ); - } - - bool all_notifications_received_tcp_and_udp() { - std::uint32_t received_twice(0); - std::uint32_t received_normal(0); - for(const auto &v : other_services_received_notification_) { - if (v.second == subscribe_notify_one_test::notifications_to_send * 2) { - received_twice++; - } else if(v.second == subscribe_notify_one_test::notifications_to_send) { - received_normal++; - } - } - - if( received_twice == (subscribe_notify_one_test::service_infos.size() - 1) / 2 - && received_normal == (subscribe_notify_one_test::service_infos.size() - 1) / 2 - 1) { - // routing manager stub receives the notification - // - twice from external nodes - // - and normal from all internal nodes - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] " - << "Received notifications:" - << " Normal: " << received_normal - << " Twice: " << received_twice; - return true; - } - return false; - } - - void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - - - while (wait_until_other_services_available_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Subscribing"; - // subscribe to events of other services - uint32_t subscribe_count = 0; - for(const subscribe_notify_one_test::service_info& i: subscribe_notify_one_test::service_infos) { - if ((i.service_id == service_info_.service_id - && i.instance_id == service_info_.instance_id) - || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { - continue; - } - - ++subscribe_count; - app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, - vsomeip::DEFAULT_MAJOR); - - VSOMEIP_DEBUG << "[" << std::hex << service_info_.service_id - << "] subscribing to Service/Instance/Eventgroup [" - << std::setw(4) << std::setfill('0') << std::hex << i.service_id << "/" - << std::setw(4) << std::setfill('0') << std::hex << i.instance_id - << "/" << std::setw(4) << std::setfill('0') << std::hex << i.eventgroup_id <<"]"; - - } - - while (wait_until_notified_from_other_services_) { - condition_.wait(its_lock); - } - - // It is possible that we run in the case a subscription is NACKED - // due to TCP endpoint not completely connected when subscription - // is processed in the server - due to resubscribing the error handler - // count may differ from expected value, but its not a real but as - // the subscription takes places anyways and all events will be received. - if (!subscription_error_occured_) { - // 4 * subscribe count cause we installed three additional wild-card handlers - ASSERT_EQ(subscribe_count * 4, subscription_state_handler_called_); - } else { - VSOMEIP_ERROR << "Subscription state handler check skipped: CallCount=" - << std::dec << subscription_state_handler_called_; - } - } - - void notify_one() { - std::unique_lock its_lock(notify_mutex_); - while(wait_for_notify_) { - notify_condition_.wait(its_lock); - } - - // sleep a while before starting to notify this is necessary as it's not - // possible to detect if _all_ clients on the remote side have - // successfully subscribed as we only receive once subscription per - // remote node no matter how many clients subscribed to this eventgroup - // on the remote node - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - - for(uint32_t i = 0; i < subscribe_notify_one_test::notifications_to_send; i++) { - std::shared_ptr its_payload = - vsomeip::runtime::get()->create_payload(); - - vsomeip::byte_t its_data[10] = {0}; - for (uint32_t j = 0; j < i+1; ++j) { - its_data[j] = static_cast(j); - } - its_payload->set_data(its_data, i+1); - - for (vsomeip::client_t client : subscribers_) { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Notifying client: " - << client << " : " << i+1; - app_->notify_one(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_payload, client); - } - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } - } - - void wait_for_stop() { - std::unique_lock its_lock(stop_mutex_); - while (wait_for_stop_) { - stop_condition_.wait(its_lock); - } - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id - << "] Received notifications from all other services, going down"; - - // wait until all notifications have been sent out - notify_thread_.join(); - - // let offer thread exit - { - std::lock_guard its_lock(mutex_); - wait_until_notified_from_other_services_ = false; - condition_.notify_one(); - } - - stop_offer(); - - // ensure that the service which hosts the routing doesn't exit to early - if (app_->is_routing()) { - for (const auto& i : subscribe_notify_one_test::service_infos) { - if ((i.service_id == service_info_.service_id - && i.instance_id == service_info_.instance_id) - || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { - continue; - } - while (app_->is_available(i.service_id, i.instance_id, - vsomeip::ANY_MAJOR, vsomeip::ANY_MINOR)) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - } - } - - for(const auto& i : subscribe_notify_one_test::service_infos) { - if ((i.service_id == service_info_.service_id - && i.instance_id == service_info_.instance_id) - || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { - continue; - } - app_->unregister_subscription_status_handler(i.service_id, i.instance_id, - i.eventgroup_id, vsomeip::ANY_EVENT); - app_->unsubscribe(i.service_id, i.instance_id, i.eventgroup_id); - app_->release_event(i.service_id, i.instance_id, i.event_id); - app_->release_service(i.service_id, i.instance_id); - } - std::this_thread::sleep_for(std::chrono::seconds(1)); - app_->clear_all_handler(); - app_->stop(); - } - -private: - subscribe_notify_one_test::service_info service_info_; - std::shared_ptr app_; - std::map, bool> other_services_available_; - std::map, std::uint32_t> other_services_received_notification_; - - bool wait_until_registered_; - bool wait_until_other_services_available_; - bool wait_until_notified_from_other_services_; - std::mutex mutex_; - std::condition_variable condition_; - std::thread offer_thread_; - - bool wait_for_stop_; - std::mutex stop_mutex_; - std::condition_variable stop_condition_; - std::thread stop_thread_; - - bool wait_for_notify_; - std::mutex notify_mutex_; - std::condition_variable notify_condition_; - std::thread notify_thread_; - - std::unordered_set subscribers_; - std::atomic subscription_state_handler_called_; - std::atomic subscription_error_occured_; - - std::mutex subscribers_mutex_; - vsomeip::reliability_type_e reliability_type_; -}; - -static unsigned long service_number; -vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN; - - -TEST(someip_subscribe_notify_one_test, send_ten_notifications_to_service) -{ - subscribe_notify_one_test_service its_sample( - subscribe_notify_one_test::service_infos[service_number], - reliability_type); -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if(argc < 3) { - std::cerr << "Please specify a service number and event reliability type, like: " << argv[0] << " 2 UDP" << std::endl; - std::cerr << "Valid service numbers are in the range of [1,6]" << std::endl; - std::cerr << "Valid service reliability types are [UDP, TCP, TCP_AND_UDP]" << std::endl; - - return 1; - } - - service_number = std::stoul(std::string(argv[1]), nullptr); - - if (std::string("TCP")== std::string(argv[2])) { - reliability_type = vsomeip::reliability_type_e::RT_RELIABLE; - } else if (std::string("UDP")== std::string(argv[2])) { - reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE; - } else if (std::string("TCP_AND_UDP")== std::string(argv[2])) { - reliability_type = vsomeip::reliability_type_e::RT_BOTH; - } - - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh b/test/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh deleted file mode 100755 index 830484d..0000000 --- a/test/subscribe_notify_one_tests/subscribe_notify_one_test_slave_starter.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 2 ] -then - echo "Please pass a json file and event reliability type to this script." - echo "For example: $0 UDP subscribe_notify_one_test_diff_client_ids_diff_ports_slave_udp.json" - exit 1 -fi - -FAIL=0 -# Start the services -export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_four -export VSOMEIP_CONFIGURATION=$2 -./subscribe_notify_one_test_service 4 $1 & - -export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_five -export VSOMEIP_CONFIGURATION=$2 -./subscribe_notify_one_test_service 5 $1 & - -export VSOMEIP_APPLICATION_NAME=subscribe_notify_one_test_service_six -export VSOMEIP_CONFIGURATION=$2 -./subscribe_notify_one_test_service 6 $1 & - -sleep 3 - -# Wait until all applications are finished -for job in $(jobs -p) -do - # Fail gets incremented if one of the binaries exits - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if both exited successfully -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master.json.in deleted file mode 100644 index 370cf98..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_master.json.in +++ /dev/null @@ -1,60 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30001", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30002", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30003", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - } - } - ], - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave.json.in deleted file mode 100644 index 46de8ff..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_autoconfig_slave.json.in +++ /dev/null @@ -1,60 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30004", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30005", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30006", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - } - } - ], - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master.json.in deleted file mode 100644 index 87299aa..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master.json.in +++ /dev/null @@ -1,76 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_one", - "id":"0x1111" - }, - { - "name":"subscribe_notify_test_service_two", - "id":"0x2222" - }, - { - "name":"subscribe_notify_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30001", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30002", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30003", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp.json.in deleted file mode 100644 index 99bf69a..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp.json.in +++ /dev/null @@ -1,73 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_one", - "id":"0x1111" - }, - { - "name":"subscribe_notify_test_service_two", - "id":"0x2222" - }, - { - "name":"subscribe_notify_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_udp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_udp.json.in deleted file mode 100644 index cb1ff9e..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_udp.json.in +++ /dev/null @@ -1,61 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_one", - "id":"0x1111" - }, - { - "name":"subscribe_notify_test_service_two", - "id":"0x2222" - }, - { - "name":"subscribe_notify_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30001" - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30002" - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30003" - } - ], - "routing":"subscribe_notify_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp.json.in deleted file mode 100644 index 4de283c..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_master_udp.json.in +++ /dev/null @@ -1,61 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_one", - "id":"0x1111" - }, - { - "name":"subscribe_notify_test_service_two", - "id":"0x2222" - }, - { - "name":"subscribe_notify_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30001" - }, - { - "service":"0x1111", - "instance":"0x0002", - "unreliable":"30002" - }, - { - "service":"0x1111", - "instance":"0x0003", - "unreliable":"30003" - } - ], - "routing":"subscribe_notify_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp.json.in deleted file mode 100644 index 5dd9299..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_same_service_id_slave_udp.json.in +++ /dev/null @@ -1,61 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_four", - "id":"0x4444" - }, - { - "name":"subscribe_notify_test_service_five", - "id":"0x5555" - }, - { - "name":"subscribe_notify_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30004" - }, - { - "service":"0x2222", - "instance":"0x0002", - "unreliable":"30005" - }, - { - "service":"0x2222", - "instance":"0x0003", - "unreliable":"30006" - } - ], - "routing":"subscribe_notify_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave.json.in deleted file mode 100644 index 5b110aa..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave.json.in +++ /dev/null @@ -1,76 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_four", - "id":"0x4444" - }, - { - "name":"subscribe_notify_test_service_five", - "id":"0x5555" - }, - { - "name":"subscribe_notify_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30004", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30005", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30006", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp.json.in deleted file mode 100644 index 628734c..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp.json.in +++ /dev/null @@ -1,73 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_four", - "id":"0x4444" - }, - { - "name":"subscribe_notify_test_service_five", - "id":"0x5555" - }, - { - "name":"subscribe_notify_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp.json.in deleted file mode 100644 index 5b96b0e..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_udp.json.in +++ /dev/null @@ -1,61 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_four", - "id":"0x4444" - }, - { - "name":"subscribe_notify_test_service_five", - "id":"0x5555" - }, - { - "name":"subscribe_notify_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30004" - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30005" - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30006" - } - ], - "routing":"subscribe_notify_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_master.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_master.json.in deleted file mode 100644 index 81bb18e..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_master.json.in +++ /dev/null @@ -1,76 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_one", - "id":"0x1111" - }, - { - "name":"subscribe_notify_test_service_two", - "id":"0x2222" - }, - { - "name":"subscribe_notify_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_slave.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_slave.json.in deleted file mode 100644 index 98ce9a6..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_partial_same_ports_slave.json.in +++ /dev/null @@ -1,76 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_four", - "id":"0x4444" - }, - { - "name":"subscribe_notify_test_service_five", - "id":"0x5555" - }, - { - "name":"subscribe_notify_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master.json.in deleted file mode 100644 index 253b55e..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master.json.in +++ /dev/null @@ -1,76 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_one", - "id":"0x1111" - }, - { - "name":"subscribe_notify_test_service_two", - "id":"0x2222" - }, - { - "name":"subscribe_notify_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp.json.in deleted file mode 100644 index 3969684..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp.json.in +++ /dev/null @@ -1,73 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_one", - "id":"0x1111" - }, - { - "name":"subscribe_notify_test_service_two", - "id":"0x2222" - }, - { - "name":"subscribe_notify_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_udp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_udp.json.in deleted file mode 100644 index 72b53fc..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_udp.json.in +++ /dev/null @@ -1,61 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_one", - "id":"0x1111" - }, - { - "name":"subscribe_notify_test_service_two", - "id":"0x2222" - }, - { - "name":"subscribe_notify_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30000" - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30000" - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30000" - } - ], - "routing":"subscribe_notify_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave.json.in deleted file mode 100644 index 556b10f..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave.json.in +++ /dev/null @@ -1,76 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_four", - "id":"0x4444" - }, - { - "name":"subscribe_notify_test_service_five", - "id":"0x5555" - }, - { - "name":"subscribe_notify_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp.json.in deleted file mode 100644 index 3f9aa0b..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp.json.in +++ /dev/null @@ -1,73 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_four", - "id":"0x4444" - }, - { - "name":"subscribe_notify_test_service_five", - "id":"0x5555" - }, - { - "name":"subscribe_notify_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_udp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_udp.json.in deleted file mode 100644 index e485690..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_udp.json.in +++ /dev/null @@ -1,61 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_four", - "id":"0x4444" - }, - { - "name":"subscribe_notify_test_service_five", - "id":"0x5555" - }, - { - "name":"subscribe_notify_test_service_six", - "id":"0x6666" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30000" - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30000" - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30000" - } - ], - "routing":"subscribe_notify_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_master.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_master.json.in deleted file mode 100644 index 88d5ec9..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_master.json.in +++ /dev/null @@ -1,31 +0,0 @@ -{ - "unicast" : "@TEST_IP_MASTER@", - "logging" : - { - "level" : "warning", - "console" : "true", - "file" : { "enable" : "false", "path" : "/var/log/vsomeip.log" }, - "dlt" : "false" - }, - "applications" : - [ - { - "name" : "subscribe_notify_test_client", - "id" : "0x9999" - } - ], - "routing" : "routingmanagerd", - "service-discovery" : - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "0", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_tcp_slave.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_tcp_slave.json.in deleted file mode 100644 index f712c07..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_tcp_slave.json.in +++ /dev/null @@ -1,39 +0,0 @@ -{ - "unicast" : "@TEST_IP_SLAVE@", - "logging" : - { - "level" : "warning", - "console" : "true", - "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, - "dlt" : "false" - }, - "applications" : - [ - { - "name" : "subscribe_notify_test_service", - "id" : "0x8888" - } - ], - "services" : - [ - { - "service" : "0xcafe", - "instance" : "0x1", - "reliable" : { "port":"30509", "enable-magic-cookies":"false" } - } - ], - "routing" : "routingmanagerd", - "service-discovery" : - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "0", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_udp_slave.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_udp_slave.json.in deleted file mode 100644 index cd6415c..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_one_event_two_eventgroups_udp_slave.json.in +++ /dev/null @@ -1,39 +0,0 @@ -{ - "unicast" : "@TEST_IP_SLAVE@", - "logging" : - { - "level" : "warning", - "console" : "true", - "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, - "dlt" : "false" - }, - "applications" : - [ - { - "name" : "subscribe_notify_test_service", - "id" : "0x8888" - } - ], - "services" : - [ - { - "service" : "0xcafe", - "instance" : "0x1", - "unreliable" : "30509" - } - ], - "routing" : "routingmanagerd", - "service-discovery" : - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "0", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_master.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_master.json.in deleted file mode 100644 index 87299aa..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_master.json.in +++ /dev/null @@ -1,76 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_one", - "id":"0x1111" - }, - { - "name":"subscribe_notify_test_service_two", - "id":"0x2222" - }, - { - "name":"subscribe_notify_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30001", - "reliable": - { - "port":"40001", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30002", - "reliable": - { - "port":"40002", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30003", - "reliable": - { - "port":"40003", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_slave.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_slave.json.in deleted file mode 100644 index bc13f01..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_diff_ports_slave.json.in +++ /dev/null @@ -1,76 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_four", - "id":"0x1111" - }, - { - "name":"subscribe_notify_test_service_five", - "id":"0x2222" - }, - { - "name":"subscribe_notify_test_service_six", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30004", - "reliable": - { - "port":"40004", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30005", - "reliable": - { - "port":"40005", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30006", - "reliable": - { - "port":"40006", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_master.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_master.json.in deleted file mode 100644 index 253b55e..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_master.json.in +++ /dev/null @@ -1,76 +0,0 @@ -{ - "unicast":"@TEST_IP_MASTER@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_one", - "id":"0x1111" - }, - { - "name":"subscribe_notify_test_service_two", - "id":"0x2222" - }, - { - "name":"subscribe_notify_test_service_three", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x1111", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x2222", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x3333", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_one", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_slave.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_slave.json.in deleted file mode 100644 index c203e80..0000000 --- a/test/subscribe_notify_tests/conf/subscribe_notify_test_same_client_ids_same_ports_slave.json.in +++ /dev/null @@ -1,76 +0,0 @@ -{ - "unicast":"@TEST_IP_SLAVE@", - "logging": - { - "level":"warning", - "console":"true", - "file": - { - "enable":"false", - "path":"/tmp/vsomeip.log" - }, - "dlt":"false" - }, - "applications": - [ - { - "name":"subscribe_notify_test_service_four", - "id":"0x1111" - }, - { - "name":"subscribe_notify_test_service_five", - "id":"0x2222" - }, - { - "name":"subscribe_notify_test_service_six", - "id":"0x3333" - } - ], - "services": - [ - { - "service":"0x4444", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x5555", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - }, - { - "service":"0x6666", - "instance":"0x0001", - "unreliable":"30000", - "reliable": - { - "port":"40000", - "enable-magic-cookies":"false" - } - } - ], - "routing":"subscribe_notify_test_service_four", - "service-discovery": - { - "enable":"true", - "multicast":"224.0.0.1", - "port":"30490", - "protocol":"udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/subscribe_notify_tests/subscribe_notify_test_globals.hpp b/test/subscribe_notify_tests/subscribe_notify_test_globals.hpp deleted file mode 100644 index 761c3c4..0000000 --- a/test/subscribe_notify_tests/subscribe_notify_test_globals.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ -#define SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ - -namespace subscribe_notify_test { - -struct service_info { - vsomeip::service_t service_id; - vsomeip::instance_t instance_id; - vsomeip::method_t method_id; - vsomeip::event_t event_id; - vsomeip::eventgroup_t eventgroup_id; -}; - -static constexpr std::array service_infos = {{ - // placeholder to be consistent w/ client ids, service ids, app names - { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }, - // node 1 - { 0x1111, 0x1, 0x1111, 0x1111, 0x1000 }, - { 0x2222, 0x1, 0x2222, 0x2222, 0x2000 }, - { 0x3333, 0x1, 0x3333, 0x3333, 0x3000 }, - // node 2 - { 0x4444, 0x1, 0x4444, 0x4444, 0x4000 }, - { 0x5555, 0x1, 0x5555, 0x5555, 0x5000 }, - { 0x6666, 0x1, 0x6666, 0x6666, 0x6000 } -}}; - -static constexpr std::array service_infos_same_service_id = {{ - // placeholder to be consistent w/ client ids, service ids, app names - { 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF }, - // node 1 - { 0x1111, 0x1, 0x1111, 0x1111, 0x1000 }, - { 0x1111, 0x2, 0x2222, 0x2222, 0x2000 }, - { 0x1111, 0x3, 0x3333, 0x3333, 0x3000 }, - // node 2 - { 0x2222, 0x1, 0x4444, 0x4444, 0x4000 }, - { 0x2222, 0x2, 0x5555, 0x5555, 0x5000 }, - { 0x2222, 0x3, 0x6666, 0x6666, 0x6000 } -}}; - -static constexpr int notifications_to_send = 10; - -// one_event_two_eventgroups globals -static constexpr struct service_info service_info_subscriber_based_notification = - { 0xCAFE, 0x1, 0x8888, 0x8111, 0x1}; -static constexpr vsomeip::method_t shutdown_method_id = 0x6666; -static constexpr vsomeip::method_t set_method_id = 0x7777; - -} - -#endif /* SUBSCRIBE_NOTIFY_TEST_GLOBALS_HPP_ */ diff --git a/test/subscribe_notify_tests/subscribe_notify_test_master_starter.sh b/test/subscribe_notify_tests/subscribe_notify_test_master_starter.sh deleted file mode 100755 index f068e99..0000000 --- a/test/subscribe_notify_tests/subscribe_notify_test_master_starter.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 1 ] -then - echo "Please pass a json file and event reliability type to this script." - echo "For example: $0 UDP subscribe_notify_test_diff_client_ids_diff_ports_master.json" - echo "To use the same service id but different instances on the node pass SAME_SERVICE_ID as third parameter" - exit 1 -fi - -# replace master with slave to be able display the correct json file to be used -# with the slave script -RELIABILITY_TYPE=$1 -MASTER_JSON_FILE=$2 -SAME_SERVICE_ID=$3 -CLIENT_JSON_FILE=${MASTER_JSON_FILE/master/slave} - -FAIL=0 - -# Start the services -export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_one -export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE -./subscribe_notify_test_service 1 $RELIABILITY_TYPE $3 & - -export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_two -export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE -./subscribe_notify_test_service 2 $RELIABILITY_TYPE $3 & - -export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_three -export VSOMEIP_CONFIGURATION=$MASTER_JSON_FILE -./subscribe_notify_test_service 3 $RELIABILITY_TYPE $3 & - -sleep 3 - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting subscribe_notify_test_slave_starter.sh on slave LXC with parameters $CLIENT_JSON_FILE $2" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./subscribe_notify_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE $3\"" & - echo "remote ssh job id: $!" -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./subscribe_notify_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE $3" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./subscribe_notify_test_slave_starter.sh $RELIABILITY_TYPE $CLIENT_JSON_FILE $3\" >> $WS_ROOT/slave_test_output 2>&1" & - -else - cat < -#endif -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "subscribe_notify_test_globals.hpp" - -class subscribe_notify_test_one_event_two_eventgroups_client { -public: - subscribe_notify_test_one_event_two_eventgroups_client( - struct subscribe_notify_test::service_info _info, bool _use_tcp) : - app_( - vsomeip::runtime::get()->create_application( - "subscribe_notify_test_client")), - info_(_info), - use_tcp_(_use_tcp), - wait_availability_(true), - wait_set_value_(true), - wait_shutdown_response_(true), - run_thread_(std::bind(&subscribe_notify_test_one_event_two_eventgroups_client::run, this)) { - } - ~subscribe_notify_test_one_event_two_eventgroups_client() { - run_thread_.join(); - } - - bool init() { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - - app_->register_state_handler( - std::bind( - &subscribe_notify_test_one_event_two_eventgroups_client::on_state, - this, std::placeholders::_1)); - - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, - std::bind( - &subscribe_notify_test_one_event_two_eventgroups_client::on_message, - this, std::placeholders::_1)); - - app_->register_availability_handler(info_.service_id, info_.instance_id, - std::bind( - &subscribe_notify_test_one_event_two_eventgroups_client::on_availability, - this, std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - - std::set its_groups; - // the service offers three events in two eventgroups - // one of the events is in both eventgroups (info_.event_id + 2) - its_groups.insert(info_.eventgroup_id); - app_->request_event(info_.service_id, info_.instance_id, - info_.event_id, its_groups, - vsomeip::event_type_e::ET_FIELD, - (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); - app_->request_event(info_.service_id, info_.instance_id, - static_cast(info_.event_id + 2), - its_groups, vsomeip::event_type_e::ET_FIELD, - (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); - its_groups.erase(info_.eventgroup_id); - its_groups.insert(static_cast(info_.eventgroup_id +1)); - app_->request_event(info_.service_id, info_.instance_id, - static_cast(info_.event_id+1), - its_groups, vsomeip::event_type_e::ET_FIELD, - (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); - app_->request_event(info_.service_id, info_.instance_id, - static_cast(info_.event_id+2), - its_groups, vsomeip::event_type_e::ET_FIELD, - (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); - - return true; - } - - void start() { - app_->start(); - } - - void stop() { - app_->clear_all_handler(); - app_->unsubscribe(info_.service_id, info_.instance_id, info_.eventgroup_id); - app_->unsubscribe(info_.service_id, info_.instance_id, static_cast(info_.eventgroup_id+1)); - app_->release_event(info_.service_id, info_.instance_id, info_.event_id); - app_->release_event(info_.service_id, info_.instance_id, static_cast(info_.event_id+1)); - app_->release_event(info_.service_id, info_.instance_id, static_cast(info_.event_id+2)); - app_->release_service(info_.service_id, info_.instance_id); - app_->stop(); - } - - void on_state(vsomeip::state_type_e _state) { - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - app_->request_service(info_.service_id, info_.instance_id); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, - bool _is_available) { - VSOMEIP_DEBUG << "Service [" - << std::setw(4) << std::setfill('0') << std::hex << _service - << "." << _instance << "] is " - << (_is_available ? "available." : "NOT available."); - if (_service == info_.service_id && _instance == info_.instance_id && _is_available) { - std::lock_guard its_lock(availability_mutex_); - wait_availability_ = false; - availability_condition_.notify_one(); - } - } - - void on_message(const std::shared_ptr &_response) { - std::stringstream its_message; - its_message << "Received a message [" - << std::setw(4) << std::setfill('0') << std::hex - << _response->get_service() << "." - << std::setw(4) << std::setfill('0') << std::hex - << _response->get_instance() << "." - << std::setw(4) << std::setfill('0') << std::hex - << _response->get_method() << "] from Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex - << _response->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _response->get_session() - << "] = "; - std::shared_ptr its_payload = - _response->get_payload(); - its_message << "(" << std::dec << its_payload->get_length() << ") "; - for (uint32_t i = 0; i < its_payload->get_length(); ++i) - its_message << std::hex << std::setw(2) << std::setfill('0') - << (int) its_payload->get_data()[i] << " "; - VSOMEIP_DEBUG << its_message.str(); - ASSERT_EQ(info_.service_id, _response->get_service()); - - if (_response->get_method() == info_.method_id - || _response->get_method() == subscribe_notify_test::shutdown_method_id) { - ASSERT_EQ(vsomeip::message_type_e::MT_RESPONSE, _response->get_message_type()); - ASSERT_EQ(vsomeip::return_code_e::E_OK, _response->get_return_code()); - std::lock_guard its_lock(shutdown_response_mutex_); - wait_shutdown_response_ = false; - shutdown_response_condition_.notify_one(); - } else if (_response->get_method() == subscribe_notify_test::set_method_id) { - std::lock_guard its_lock(set_value_mutex_); - wait_set_value_ = false; - set_value_condition_.notify_one(); - } else if (_response->get_method() >= info_.event_id - && _response->get_method() <= static_cast(info_.event_id + 3)) { - std::lock_guard its_lock(events_mutex_); - received_events_.push_back(_response->get_payload()); - if (received_events_.size() > 4) { - ADD_FAILURE() << "Received too many events [" - << std::hex << _response->get_method() - << " (" << std::dec << received_events_.size() << ")"; - } - number_received_events_[_response->get_method()]++; - events_condition_.notify_one(); - } else { - ADD_FAILURE() << "Received unknown method id: " << std::setw(4) - << std::setfill('0') << std::hex << _response->get_method(); - } - - } - - void set_field_at_service(vsomeip::byte_t _value) { - std::shared_ptr its_runtime = vsomeip::runtime::get(); - std::shared_ptr its_request = its_runtime->create_request(false); - its_request->set_service(info_.service_id); - its_request->set_instance(info_.instance_id); - its_request->set_method(subscribe_notify_test::set_method_id); - its_request->set_reliable(use_tcp_); - std::shared_ptr its_payload = its_runtime->create_payload(&_value, sizeof(_value)); - its_request->set_payload(its_payload); - app_->send(its_request); - } - - void call_method_at_service(vsomeip::method_t _method) { - std::shared_ptr its_runtime = vsomeip::runtime::get(); - std::shared_ptr its_request = its_runtime->create_request(false); - its_request->set_service(info_.service_id); - its_request->set_instance(info_.instance_id); - its_request->set_method(_method); - its_request->set_reliable(use_tcp_); - app_->send(its_request); - } - - void wait_on_condition(std::unique_lock&& _lock, bool *_predicate, std::condition_variable&& _condition, std::uint32_t _timeout) { - while (*_predicate) { - if (std::cv_status::timeout == _condition.wait_for(_lock, std::chrono::seconds(_timeout))) { - ADD_FAILURE() << "Condition variable wasn't notified within time (" - << _timeout << "sec)"; - } - } - *_predicate = true; - } - - void subscribe_at_service() { - // subscribe to both eventgroups - app_->subscribe(info_.service_id, info_.instance_id, info_.eventgroup_id); - app_->subscribe(info_.service_id, info_.instance_id, static_cast(info_.eventgroup_id+1)); - } - - void unsubscribe_at_service() { - app_->unsubscribe(info_.service_id, info_.instance_id, info_.eventgroup_id); - app_->unsubscribe(info_.service_id, info_.instance_id, static_cast(info_.eventgroup_id+1)); - } - - void wait_for_events(std::unique_lock&& _lock, - std::uint32_t _expected_number_received_events, - std::condition_variable&& _condition) { - std::cv_status its_status(std::cv_status::no_timeout); - while (received_events_.size() != _expected_number_received_events - && its_status != std::cv_status::timeout) { - its_status = _condition.wait_for(_lock, std::chrono::seconds(15)); - if (std::cv_status::timeout == its_status) { - ADD_FAILURE() << "Didn't receive expected number of events: " - << _expected_number_received_events - << " within time. Instead received: " << received_events_.size(); - } - } - ASSERT_EQ(size_t(_expected_number_received_events), received_events_.size()); - } - - void check_received_events_payload(vsomeip::byte_t _value) { - for (const auto &p : received_events_) { - ASSERT_EQ(vsomeip::length_t(1), p->get_length()); - ASSERT_EQ(vsomeip::byte_t(_value), *p->get_data()); - } - received_events_.clear(); - } - - void check_received_events_number(std::set> _expected) { - for (const auto &e : _expected) { - auto event = number_received_events_.find(e.first); - ASSERT_NE(number_received_events_.end(), event); - ASSERT_EQ(e.second, event->second); - } - number_received_events_.clear(); - } - - void run() { - std::unique_lock its_availability_lock(availability_mutex_); - wait_on_condition(std::move(its_availability_lock), &wait_availability_, std::move(availability_condition_), 300); - // service is available now - - for (int i = 0; i < 3; i++) { - // set value - set_field_at_service(0x1); - { - std::unique_lock its_set_value_lock(set_value_mutex_); - wait_on_condition(std::move(its_set_value_lock), &wait_set_value_, std::move(set_value_condition_), 30); - } - - // subscribe - std::unique_lock its_events_lock(events_mutex_); - subscribe_at_service(); - wait_for_events(std::move(its_events_lock), 4, std::move(events_condition_)); - check_received_events_payload(0x1); - - std::set> its_expected; - its_expected.insert({info_.event_id, 1}); - its_expected.insert({static_cast(info_.event_id+1), 1}); - // Initial event for the event which is member of both eventgroups has to be sent twice - its_expected.insert({static_cast(info_.event_id+2), 2}); - - check_received_events_number(its_expected); - its_expected.clear(); - // set value again - set_field_at_service(0x2); - { - std::unique_lock its_set_value_lock(set_value_mutex_); - wait_on_condition(std::move(its_set_value_lock), &wait_set_value_, std::move(set_value_condition_), 30); - } - - wait_for_events(std::move(its_events_lock), 3, std::move(events_condition_)); - check_received_events_payload(0x2); - its_expected.insert({info_.event_id, 1}); - its_expected.insert({static_cast(info_.event_id+1), 1}); - its_expected.insert({static_cast(info_.event_id+2), 1}); - - check_received_events_number(its_expected); - its_expected.clear(); - - // set value again - set_field_at_service(0x3); - { - std::unique_lock its_set_value_lock(set_value_mutex_); - wait_on_condition(std::move(its_set_value_lock), &wait_set_value_, std::move(set_value_condition_), 30); - } - wait_for_events(std::move(its_events_lock), 3, std::move(events_condition_)); - check_received_events_payload(0x3); - its_expected.insert({info_.event_id, 1}); - its_expected.insert({static_cast(info_.event_id+1), 1}); - its_expected.insert({static_cast(info_.event_id+2), 1}); - check_received_events_number(its_expected); - - unsubscribe_at_service(); - // sleep some time to ensure the unsubscription was processed by the - // remote routing_manager before setting the field again in the next - // loop. - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - } - std::unique_lock its_shutdown_lock(shutdown_response_mutex_); - call_method_at_service(subscribe_notify_test::shutdown_method_id); - wait_on_condition(std::move(its_shutdown_lock), &wait_shutdown_response_, std::move(shutdown_response_condition_), 30); - stop(); - } - -private: - std::shared_ptr app_; - struct subscribe_notify_test::service_info info_; - bool use_tcp_; - - bool wait_availability_; - std::mutex availability_mutex_; - std::condition_variable availability_condition_; - - bool wait_set_value_; - std::mutex set_value_mutex_; - std::condition_variable set_value_condition_; - - bool wait_shutdown_response_; - std::mutex shutdown_response_mutex_; - std::condition_variable shutdown_response_condition_; - - std::mutex events_mutex_; - std::condition_variable events_condition_; - - std::vector> received_events_; - std::map number_received_events_; - std::thread run_thread_; -}; - -#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING - subscribe_notify_test_one_event_two_eventgroups_client *its_client_ptr(nullptr); - void handle_signal(int _signal) { - if (its_client_ptr != nullptr && - (_signal == SIGINT || _signal == SIGTERM)) - its_client_ptr->stop(); - } -#endif - -static bool use_tcp; - -TEST(someip_subscribe_notify_test_one_event_two_eventgroups, subscribe_to_service) -{ - subscribe_notify_test_one_event_two_eventgroups_client its_client( - subscribe_notify_test::service_info_subscriber_based_notification, use_tcp); -#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING - its_client_ptr = &its_client; - signal(SIGINT, handle_signal); - signal(SIGTERM, handle_signal); -#endif - if (its_client.init()) { - its_client.start(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if(argc < 2) { - std::cerr << "Please specify a offer type of the service, like: " << argv[0] << " UDP" << std::endl; - std::cerr << "Valid offer types include:" << std::endl; - std::cerr << "[UDP, TCP]" << std::endl; - return 1; - } - - if(std::string("TCP") == std::string(argv[1])) { - use_tcp = true; - } else if(std::string("UDP") == std::string(argv[1])) { - use_tcp = false; - } else { - std::cerr << "Wrong subscription type passed, exiting" << std::endl; - std::cerr << "Valid subscription types include:" << std::endl; - std::cerr << "[UDP, TCP]" << std::endl; - return 1; - } - - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master_starter.sh b/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master_starter.sh deleted file mode 100755 index c453796..0000000 --- a/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_master_starter.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 2 ]; then - echo "Please pass a json file and a subscription type to this script." - echo "Valid subscription types include:" - echo " [UDP, TCP]" - echo "For example: $0 UDP subscribe_notify_test_one_event_two_eventgroups_master.json" - exit 1 -fi - -# replace master with slave to be able display the correct json file to be used -# with the slave script -RELIABILITY_TYPE=$1 -MASTER_JSON_FILE=$2 -if [ $1 == "UDP" ]; then - SLAVE_JSON_FILE=${MASTER_JSON_FILE/master/udp_slave} -elif [ $1 == "TCP" ]; then - SLAVE_JSON_FILE=${MASTER_JSON_FILE/master/tcp_slave} -fi - -FAIL=0 - -export VSOMEIP_CONFIGURATION=$2 -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -# Start the client -./subscribe_notify_test_one_event_two_eventgroups_client $1 & -PID_CLIENT=$! -sleep 1 - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting subscribe_notify_test_slave_starter.sh on slave LXC with parameters $SLAVE_JSON_FILE" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh $RELIABILITY_TYPE $SLAVE_JSON_FILE\"" & - echo "remote ssh job id: $!" -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh $RELIABILITY_TYPE $SLAVE_JSON_FILE" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh $RELIABILITY_TYPE $SLAVE_JSON_FILE\" >> $WS_ROOT/slave_test_output 2>&1" & - -else - cat < -#endif -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "subscribe_notify_test_globals.hpp" - -class subscribe_notify_test_one_event_two_eventgroups_service { -public: - subscribe_notify_test_one_event_two_eventgroups_service(subscribe_notify_test::service_info _info, bool _use_tcp) : - app_(vsomeip::runtime::get()->create_application()), - wait_for_shutdown_(true), - info_(_info), - notify_thread_(std::bind(&subscribe_notify_test_one_event_two_eventgroups_service::wait_for_shutdown, this)), - use_tcp_(_use_tcp) { - } - - ~subscribe_notify_test_one_event_two_eventgroups_service() { - notify_thread_.join(); - } - - bool init() { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return false; - } - app_->register_state_handler( - std::bind(&subscribe_notify_test_one_event_two_eventgroups_service::on_state, this, - std::placeholders::_1)); - - app_->register_message_handler( - info_.service_id, - info_.instance_id, - subscribe_notify_test::set_method_id, - std::bind(&subscribe_notify_test_one_event_two_eventgroups_service::on_set, this, - std::placeholders::_1)); - - app_->register_message_handler( - info_.service_id, - info_.instance_id, - info_.method_id, - std::bind(&subscribe_notify_test_one_event_two_eventgroups_service::on_message, this, - std::placeholders::_1)); - - app_->register_message_handler( - info_.service_id, - info_.instance_id, - subscribe_notify_test::shutdown_method_id, - std::bind(&subscribe_notify_test_one_event_two_eventgroups_service::on_shutdown, this, - std::placeholders::_1)); - - std::set its_groups; - // the service offers three events in two eventgroups - // one of the events is in both eventgroups - its_groups.insert(info_.eventgroup_id); - app_->offer_event(info_.service_id, info_.instance_id, - info_.event_id, its_groups, vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), - false, true, nullptr, - (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); - app_->offer_event(info_.service_id, info_.instance_id, - static_cast(info_.event_id + 2), - its_groups, vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), - false, true, nullptr, - (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); - its_groups.erase(info_.eventgroup_id); - its_groups.insert(static_cast(info_.eventgroup_id + 1)); - app_->offer_event(info_.service_id, info_.instance_id, - static_cast(info_.event_id + 1), - its_groups, vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), - false, true, nullptr, - (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); - app_->offer_event(info_.service_id, info_.instance_id, - static_cast(info_.event_id + 2), - its_groups, vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), - false, true, nullptr, - (use_tcp_ ? vsomeip::reliability_type_e::RT_RELIABLE : vsomeip::reliability_type_e::RT_UNRELIABLE)); - payload_ = vsomeip::runtime::get()->create_payload(); - - return true; - } - - void start() { - app_->start(); - } - -#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING - /* - * Handle signal to shutdown - */ - void stop() { - { - std::lock_guard its_lock(shutdown_mutex_); - wait_for_shutdown_ = false; - shutdown_condition_.notify_one(); - } - app_->clear_all_handler(); - stop_offer(); - notify_thread_.join(); - app_->stop(); - } -#endif - - void offer() { - app_->offer_service(info_.service_id, info_.instance_id); - } - - void stop_offer() { - app_->stop_offer_service(info_.service_id, info_.instance_id); - } - - void on_state(vsomeip::state_type_e _state) { - std::cout << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered.") << std::endl; - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - offer(); - } - } - - void on_shutdown(const std::shared_ptr &_message) { - std::shared_ptr its_response - = vsomeip::runtime::get()->create_response(_message); - its_response->set_payload(payload_); - app_->send(its_response); - { - std::lock_guard its_lock(shutdown_mutex_); - wait_for_shutdown_ = false; - shutdown_condition_.notify_one(); - } - } - - void on_set(const std::shared_ptr &_message) { - std::shared_ptr its_response - = vsomeip::runtime::get()->create_response(_message); - payload_ = _message->get_payload(); - its_response->set_payload(payload_); - app_->send(its_response); - app_->notify(info_.service_id, info_.instance_id, info_.event_id, payload_); - app_->notify(info_.service_id, info_.instance_id, static_cast(info_.event_id + 1), payload_); - app_->notify(info_.service_id, info_.instance_id, static_cast(info_.event_id + 2), payload_); - } - - void on_message(const std::shared_ptr &_message) { - app_->send(vsomeip::runtime::get()->create_response(_message)); - } - - void wait_for_shutdown() { - { - std::unique_lock its_lock(shutdown_mutex_); - while (wait_for_shutdown_) { - shutdown_condition_.wait(its_lock); - } - wait_for_shutdown_= true; - } - - app_->clear_all_handler(); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - stop_offer(); - app_->stop(); - } - -private: - std::shared_ptr app_; - - std::mutex shutdown_mutex_; - bool wait_for_shutdown_; - std::condition_variable shutdown_condition_; - - std::shared_ptr payload_; - - subscribe_notify_test::service_info info_; - - std::thread notify_thread_; - bool use_tcp_; -}; - -#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING - subscribe_notify_test_one_event_two_eventgroups_service *its_service_ptr(nullptr); - void handle_signal(int _signal) { - if (its_service_ptr != nullptr && - (_signal == SIGINT || _signal == SIGTERM)) - its_service_ptr->stop(); - } -#endif - -static bool use_tcp; - -TEST(someip_subscribe_notify_test_one_event_two_eventgroups, wait_for_attribute_set) -{ - subscribe_notify_test_one_event_two_eventgroups_service its_service( - subscribe_notify_test::service_info_subscriber_based_notification, use_tcp); -#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING - its_service_ptr = &its_service; - signal(SIGINT, handle_signal); - signal(SIGTERM, handle_signal); -#endif - if (its_service.init()) { - its_service.start(); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if(argc < 2) { - std::cerr << "Please specify a offer type of the service, like: " << argv[0] << " UDP" << std::endl; - std::cerr << "Valid offer types include:" << std::endl; - std::cerr << "[UDP, TCP]" << std::endl; - return 1; - } - - if(std::string("TCP") == std::string(argv[1])) { - use_tcp = true; - } else if(std::string("UDP") == std::string(argv[1])) { - use_tcp = false; - } else { - std::cerr << "Wrong subscription type passed, exiting" << std::endl; - std::cerr << "Valid subscription types include:" << std::endl; - std::cerr << "[UDP, TCP]" << std::endl; - return 1; - } - - return RUN_ALL_TESTS(); -} -#endif - - diff --git a/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh b/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh deleted file mode 100755 index 0d663d6..0000000 --- a/test/subscribe_notify_tests/subscribe_notify_test_one_event_two_eventgroups_slave_starter.sh +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 2 ]; then - echo "Please pass a json file and a subscription type to this script." - echo "Valid subscription types include:" - echo " [UDP, TCP]" - echo "For example: $0 UDP subscribe_notify_test_one_event_two_eventgroups_udp_slave.json" - exit 1 -fi - -FAIL=0 - -export VSOMEIP_CONFIGURATION=$2 -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -# Start the services -./subscribe_notify_test_one_event_two_eventgroups_service $1 & -PID_SERVICE=$! - -# wait until service exits successfully -wait $PID_SERVICE || FAIL=$(($FAIL+1)) - -# kill daemon -kill $PID_VSOMEIPD -wait $PID_VSOMEIPD || FAIL=$(($FAIL+1)) - - -# Check if both exited successfully -if [ $FAIL -eq 0 ]; then - exit 0 -else - exit 1 -fi diff --git a/test/subscribe_notify_tests/subscribe_notify_test_service.cpp b/test/subscribe_notify_tests/subscribe_notify_test_service.cpp deleted file mode 100644 index c522d1a..0000000 --- a/test/subscribe_notify_tests/subscribe_notify_test_service.cpp +++ /dev/null @@ -1,512 +0,0 @@ -// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include "subscribe_notify_test_globals.hpp" - - -class subscribe_notify_test_service { -public: - subscribe_notify_test_service(struct subscribe_notify_test::service_info _service_info, - std::array _service_infos, - vsomeip::reliability_type_e _reliability_type) : - service_info_(_service_info), - service_infos_(_service_infos), - app_(vsomeip::runtime::get()->create_application()), - wait_until_registered_(true), - wait_until_other_services_available_(true), - wait_until_notified_from_other_services_(true), - offer_thread_(std::bind(&subscribe_notify_test_service::run, this)), - wait_for_stop_(true), - stop_thread_(std::bind(&subscribe_notify_test_service::wait_for_stop, this)), - wait_for_notify_(true), - notify_thread_(std::bind(&subscribe_notify_test_service::notify, this)), - subscription_state_handler_called_(0), - subscription_error_occured_(false), - reliability_type_(_reliability_type) { - if (!app_->init()) { - ADD_FAILURE() << "Couldn't initialize application"; - return; - } - - app_->register_state_handler( - std::bind(&subscribe_notify_test_service::on_state, this, - std::placeholders::_1)); - app_->register_message_handler(service_info_.service_id, - service_info_.instance_id, service_info_.method_id, - std::bind(&subscribe_notify_test_service::on_request, this, - std::placeholders::_1)); - app_->register_message_handler(vsomeip::ANY_SERVICE, - vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, - std::bind(&subscribe_notify_test_service::on_message, this, - std::placeholders::_1)); - - // offer event - std::set its_eventgroups; - its_eventgroups.insert(service_info_.eventgroup_id); - app_->offer_event(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_eventgroups, - vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(), - false, true, nullptr, reliability_type_); - - - // register availability for all other services and request their event. - for(const auto& i : service_infos_) { - if ((i.service_id == service_info_.service_id - && i.instance_id == service_info_.instance_id) - || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { - continue; - } - app_->request_service(i.service_id, i.instance_id); - app_->register_availability_handler(i.service_id, i.instance_id, - std::bind(&subscribe_notify_test_service::on_availability, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3)); - - auto handler = std::bind(&subscribe_notify_test_service::on_subscription_state_change, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4, std::placeholders::_5); - app_->register_subscription_status_handler(i.service_id, i.instance_id, i.eventgroup_id, vsomeip::ANY_EVENT, handler); - - - std::set its_eventgroups; - its_eventgroups.insert(i.eventgroup_id); - app_->request_event(i.service_id, i.instance_id, i.event_id, its_eventgroups, vsomeip::event_type_e::ET_FIELD, reliability_type_); - - other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; - other_services_received_notification_[std::make_pair(i.service_id, i.method_id)] = 0; - } - - // register subscription handler to detect whether or not all other - // other services have subscribed - app_->register_subscription_handler(service_info_.service_id, - service_info_.instance_id, service_info_.eventgroup_id, - std::bind(&subscribe_notify_test_service::on_subscription, this, - std::placeholders::_1, std::placeholders::_2, - std::placeholders::_3, std::placeholders::_4)); - - app_->start(); - } - - ~subscribe_notify_test_service() { - offer_thread_.join(); - stop_thread_.join(); - } - - void offer() { - app_->offer_service(service_info_.service_id, service_info_.instance_id); - } - - void stop_offer() { - app_->stop_offer_event(service_info_.service_id, service_info_.instance_id, service_info_.event_id); - app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); - } - - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_INFO << "Application " << app_->get_name() << " is " - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "deregistered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - std::lock_guard its_lock(mutex_); - wait_until_registered_ = false; - condition_.notify_one(); - } - } - - void on_availability(vsomeip::service_t _service, - vsomeip::instance_t _instance, bool _is_available) { - if(_is_available) { - auto its_service = other_services_available_.find(std::make_pair(_service, _instance)); - if(its_service != other_services_available_.end()) { - if(its_service->second != _is_available) { - its_service->second = true; - VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Service [" - << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance - << "] is available."; - - } - } - - if(std::all_of(other_services_available_.cbegin(), - other_services_available_.cend(), - [](const std::map, bool>::value_type& v) { - return v.second;})) { - std::lock_guard its_lock(mutex_); - wait_until_other_services_available_ = false; - condition_.notify_one(); - } - } - } - - void on_subscription_state_change(const vsomeip::service_t _service, const vsomeip::instance_t _instance, - const vsomeip::eventgroup_t _eventgroup, const vsomeip::event_t _event, const uint16_t _error) { - (void)_service; - (void)_instance; - (void)_eventgroup; - (void)_event; - - if (!_error) { - subscription_state_handler_called_++; - } else { - subscription_error_occured_ = true; - VSOMEIP_WARNING << std::hex << app_->get_client() - << " : on_subscription_state_change: for service " << std::hex - << _service << " received a subscription error!"; - } - } - - bool on_subscription(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, - bool _subscribed) { - (void)_uid; - (void)_gid; - std::lock_guard its_lock(subscribers_mutex_); - static bool notified(false); - if (_subscribed) { - subscribers_.insert(_client); - } else { - subscribers_.erase(_client); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] " << "Client: " - << std::setw(4) << std::setfill('0') << std::hex << _client - << (_subscribed ? " subscribed" : " unsubscribed") - << ", now have " << std::dec << subscribers_.size() - << " subscribers" ; - // check if all other services have subscribed: - // -1 for placeholder in array - // divide by two because we only receive once subscription per remote node - // no matter how many clients subscribed to this eventgroup on the remote node - if (!notified && subscribers_.size() == (service_infos_.size() - 1) / 2 ) - { - // notify the notify thread to start sending out notifications - std::lock_guard its_lock(notify_mutex_); - wait_for_notify_ = false; - notify_condition_.notify_one(); - notified = true; - } - return true; - } - - void on_request(const std::shared_ptr &_message) { - if(_message->get_message_type() == vsomeip::message_type_e::MT_REQUEST) { - VSOMEIP_DEBUG << "Received a request with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_session() << "]"; - std::shared_ptr its_response = vsomeip::runtime::get() - ->create_response(_message); - app_->send(its_response); - } - } - - void on_message(const std::shared_ptr &_message) { - if(_message->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) { - - other_services_received_notification_[std::make_pair(_message->get_service(), - _message->get_method())]++; - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] " - << "Received a notification with Client/Session [" << std::setw(4) - << std::setfill('0') << std::hex << _message->get_client() << "/" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_session() << "] from Service/Method [" - << std::setw(4) << std::setfill('0') << std::hex - << _message->get_service() << "/" << std::setw(4) << std::setfill('0') - << std::hex << _message->get_method() << "/" << std::dec << _message->get_length() << "] (now have: " - << std::dec << other_services_received_notification_[std::make_pair(_message->get_service(), - _message->get_method())] << ")"; - - if(all_notifications_received()) { - std::lock_guard its_lock(stop_mutex_); - wait_for_stop_ = false; - stop_condition_.notify_one(); - } - } - } - - bool all_notifications_received() { - return std::all_of( - other_services_received_notification_.cbegin(), - other_services_received_notification_.cend(), - [&](const std::map, std::uint32_t>::value_type& v) - { - return v.second == subscribe_notify_test::notifications_to_send; - } - ); - } - - bool all_notifications_received_tcp_and_udp() { - std::uint32_t received_twice(0); - std::uint32_t received_normal(0); - for(const auto &v : other_services_received_notification_) { - if (v.second == subscribe_notify_test::notifications_to_send * 2) { - received_twice++; - } else if(v.second == subscribe_notify_test::notifications_to_send) { - received_normal++; - } - } - - if( received_twice == (service_infos_.size() - 1) / 2 - && received_normal == (service_infos_.size() - 1) / 2 - 1) { - // routing manager stub receives the notification - // - twice from external nodes - // - and normal from all internal nodes - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] " - << "Received notifications:" - << " Normal: " << received_normal - << " Twice: " << received_twice; - return true; - } - return false; - } - - void run() { - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Running"; - std::unique_lock its_lock(mutex_); - while (wait_until_registered_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Offering"; - offer(); - - - while (wait_until_other_services_available_) { - condition_.wait(its_lock); - } - - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Subscribing"; - // subscribe to events of other services - uint32_t subscribe_count = 0; - for(const subscribe_notify_test::service_info& i: service_infos_) { - if ((i.service_id == service_info_.service_id - && i.instance_id == service_info_.instance_id) - || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { - continue; - } - ++subscribe_count; - app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id, - vsomeip::DEFAULT_MAJOR); - VSOMEIP_DEBUG << "[" << std::hex << service_info_.service_id - << "] subscribing to Service/Instance/Eventgroup [" - << std::setw(4) << std::setfill('0') << std::hex << i.service_id << "/" - << std::setw(4) << std::setfill('0') << std::hex << i.instance_id - << "/" << std::setw(4) << std::setfill('0') << std::hex << i.eventgroup_id <<"]"; - } - - while (wait_until_notified_from_other_services_) { - condition_.wait(its_lock); - } - - // It is possible that we run in the case a subscription is NACKED - // due to TCP endpoint not completely connected when subscription - // is processed in the server - due to resubscribing the error handler - // count may differ from expected value, but its not a real but as - // the subscription takes places anyways and all events will be received. - if (!subscription_error_occured_) { - ASSERT_EQ(subscribe_count, subscription_state_handler_called_); - } else { - VSOMEIP_WARNING << "Subscription state handler check skipped: CallCount=" - << std::dec << subscription_state_handler_called_; - } - } - - void notify() { - std::unique_lock its_lock(notify_mutex_); - while (wait_for_notify_) { - notify_condition_.wait(its_lock); - } - - // sleep a while before starting to notify this is necessary as it's not - // possible to detect if _all_ clients on the remote side have - // successfully subscribed as we only receive once subscription per - // remote node no matter how many clients subscribed to this eventgroup - // on the remote node - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - - VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Starting to notify"; - - for(uint32_t i = 0; i < subscribe_notify_test::notifications_to_send; i++) { - std::shared_ptr its_payload = - vsomeip::runtime::get()->create_payload(); - - vsomeip::byte_t its_data[10] = {0}; - for (uint32_t j = 0; j < i+1; ++j) { - its_data[j] = static_cast(j); - } - its_payload->set_data(its_data, i+1); - VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id << "] Notifying: " << i+1; - app_->notify(service_info_.service_id, service_info_.instance_id, - service_info_.event_id, its_payload); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - } - - void wait_for_stop() { - std::unique_lock its_lock(stop_mutex_); - while (wait_for_stop_) { - stop_condition_.wait(its_lock); - } - - // wait until all notifications have been sent out - notify_thread_.join(); - - VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex - << service_info_.service_id - << "] Received notifications from all other services, going down"; - - // let offer thread exit - { - std::lock_guard its_lock(mutex_); - wait_until_notified_from_other_services_ = false; - condition_.notify_one(); - } - - stop_offer(); - - // ensure that the service which hosts the routing doesn't exit to early - if (app_->is_routing()) { - for (const auto& i : service_infos_) { - if ((i.service_id == service_info_.service_id - && i.instance_id == service_info_.instance_id) - || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { - continue; - } - while (app_->is_available(i.service_id, i.instance_id, - vsomeip::ANY_MAJOR, vsomeip::ANY_MINOR)) { - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - } - } - - std::this_thread::sleep_for(std::chrono::seconds(1)); - for(const auto& i : service_infos_) { - if ((i.service_id == service_info_.service_id - && i.instance_id == service_info_.instance_id) - || (i.service_id == 0xFFFF && i.instance_id == 0xFFFF)) { - continue; - } - app_->unregister_subscription_status_handler(i.service_id, i.instance_id, - i.eventgroup_id, vsomeip::ANY_EVENT); - app_->unsubscribe(i.service_id, i.instance_id, i.eventgroup_id); - app_->release_event(i.service_id, i.instance_id, i.event_id); - app_->release_service(i.service_id, i.instance_id); - } - app_->clear_all_handler(); - app_->stop(); - } - -private: - subscribe_notify_test::service_info service_info_; - std::array service_infos_; - std::shared_ptr app_; - std::map, bool> other_services_available_; - std::map, std::uint32_t> other_services_received_notification_; - - bool wait_until_registered_; - bool wait_until_other_services_available_; - bool wait_until_notified_from_other_services_; - std::mutex mutex_; - std::condition_variable condition_; - std::thread offer_thread_; - - bool wait_for_stop_; - std::mutex stop_mutex_; - std::condition_variable stop_condition_; - std::thread stop_thread_; - - std::set subscribers_; - bool wait_for_notify_; - std::mutex notify_mutex_; - std::condition_variable notify_condition_; - std::thread notify_thread_; - std::atomic subscription_state_handler_called_; - std::atomic subscription_error_occured_; - - std::mutex subscribers_mutex_; - vsomeip::reliability_type_e reliability_type_; -}; - -static unsigned long service_number; -static bool use_same_service_id; -vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN; - - -TEST(someip_subscribe_notify_test, send_ten_notifications_to_service) -{ - if(use_same_service_id) { - subscribe_notify_test_service its_sample( - subscribe_notify_test::service_infos_same_service_id[service_number], - subscribe_notify_test::service_infos_same_service_id, - reliability_type); - } else { - subscribe_notify_test_service its_sample( - subscribe_notify_test::service_infos[service_number], - subscribe_notify_test::service_infos, - reliability_type); - } -} - -#ifndef _WIN32 -int main(int argc, char** argv) -{ - ::testing::InitGoogleTest(&argc, argv); - if(argc < 2) { - std::cerr << "Please specify a service number and event reliability type, like: " << argv[0] << " 2 UDP SAME_SERVICE_ID" << std::endl; - std::cerr << "Valid service numbers are in the range of [1,6]" << std::endl; - std::cerr << "Valid event reliability types are [UDP, TCP, TCP_AND_UDP]" << std::endl; - std::cerr << "If SAME_SERVICE_ID is specified as third parameter the test is run w/ multiple instances of the same service" << std::endl; - return 1; - } - - service_number = std::stoul(std::string(argv[1]), nullptr); - - if (argc >= 3) { - if (std::string("TCP")== std::string(argv[2])) { - reliability_type = vsomeip::reliability_type_e::RT_RELIABLE; - } else if (std::string("UDP")== std::string(argv[2])) { - reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE; - } else if (std::string("TCP_AND_UDP")== std::string(argv[2])) { - reliability_type = vsomeip::reliability_type_e::RT_BOTH; - } - } - - if (argc >= 4 && std::string("SAME_SERVICE_ID") == std::string(argv[3])) { - use_same_service_id = true; - } else { - use_same_service_id = false; - } - - - - return RUN_ALL_TESTS(); -} -#endif diff --git a/test/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh b/test/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh deleted file mode 100755 index 8133161..0000000 --- a/test/subscribe_notify_tests/subscribe_notify_test_slave_starter.sh +++ /dev/null @@ -1,55 +0,0 @@ -#!/bin/bash -# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -if [ $# -lt 1 ] -then - echo "Please pass a json file to this script." - echo "For example: $0 UDP subscribe_notify_test_diff_client_ids_diff_ports_slave.json" - echo "To use the same service id but different instances on the node pass SAME_SERVICE_ID as third parameter" - exit 1 -fi - -RELIABILITY_TYPE=$1 -SLAVE_JSON_FILE=$2 -SAME_SERVICE_ID=$3 - -FAIL=0 -# Start the services -export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_four -export VSOMEIP_CONFIGURATION=$SLAVE_JSON_FILE -./subscribe_notify_test_service 4 $RELIABILITY_TYPE $3 & - -export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_five -export VSOMEIP_CONFIGURATION=$SLAVE_JSON_FILE -./subscribe_notify_test_service 5 $RELIABILITY_TYPE $3 & - -export VSOMEIP_APPLICATION_NAME=subscribe_notify_test_service_six -export VSOMEIP_CONFIGURATION=$SLAVE_JSON_FILE -./subscribe_notify_test_service 6 $RELIABILITY_TYPE $3 & - -sleep 3 - -# Wait until all applications are finished -for job in $(jobs -p) -do - # Fail gets incremented if one of the binaries exits - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if both exited successfully -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi diff --git a/test/suspend_resume_tests/conf/suspend_resume_test_client.json.in b/test/suspend_resume_tests/conf/suspend_resume_test_client.json.in deleted file mode 100644 index db94cea..0000000 --- a/test/suspend_resume_tests/conf/suspend_resume_test_client.json.in +++ /dev/null @@ -1,32 +0,0 @@ -{ - "unicast" : "@TEST_IP_SLAVE@", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : { "enable" : "false", "path" : "" }, - "dlt" : "false" - }, - "applications" : - [ - { - "name" : "suspend_resume_test_client", - "id" : "0x4567" - } - ], - "routing" : "suspend_resume_test_client", - "service-discovery" : - { - "enable" : "true", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/suspend_resume_tests/conf/suspend_resume_test_service.json.in b/test/suspend_resume_tests/conf/suspend_resume_test_service.json.in deleted file mode 100644 index 44b510b..0000000 --- a/test/suspend_resume_tests/conf/suspend_resume_test_service.json.in +++ /dev/null @@ -1,40 +0,0 @@ -{ - "unicast" : "@TEST_IP_MASTER@", - "netmask" : "255.255.255.0", - "logging" : - { - "level" : "debug", - "console" : "true", - "file" : { "enable" : "false", "path" : "" }, - "dlt" : "false" - }, - "applications" : - [ - { - "name" : "suspend_resume_test_service", - "id" : "0x7654" - } - ], - "services" : - [ - { - "service" : "0x6311", - "instance" : "0x0002", - "unreliable" : "34504" - } - ], - "routing" : "routingmanagerd", - "service-discovery" : - { - "enable" : "true", - "multicast" : "224.0.0.1", - "port" : "30490", - "protocol" : "udp", - "initial_delay_min" : "10", - "initial_delay_max" : "10", - "repetitions_base_delay" : "30", - "repetitions_max" : "3", - "cyclic_offer_delay" : "1000", - "ttl" : "3" - } -} \ No newline at end of file diff --git a/test/suspend_resume_tests/suspend_resume_test.hpp b/test/suspend_resume_tests/suspend_resume_test.hpp deleted file mode 100644 index 5271bba..0000000 --- a/test/suspend_resume_tests/suspend_resume_test.hpp +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef SUSPEND_RESUME_TEST_ -#define SUSPEND_RESUME_TEST_ - -#define TEST_SERVICE 0x6311 -#define TEST_INSTANCE 0x0002 -#define TEST_MAJOR 0x01 -#define TEST_MINOR 0x0 - -#define TEST_EVENT 0x8005 -#define TEST_EVENTGROUP 0x0002 - -#define TEST_METHOD 0x0001 - -#define TEST_SUSPEND 0x00 -#define TEST_STOP 0xFF - -#endif // SUSPEND_RESUME_TEST_ diff --git a/test/suspend_resume_tests/suspend_resume_test_client.cpp b/test/suspend_resume_tests/suspend_resume_test_client.cpp deleted file mode 100644 index ca2956c..0000000 --- a/test/suspend_resume_tests/suspend_resume_test_client.cpp +++ /dev/null @@ -1,239 +0,0 @@ -// Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include -#include -#include - -#include - -#include -#include - -#include "suspend_resume_test.hpp" - -class suspend_resume_test_client { -public: - suspend_resume_test_client() - : name_("suspend_resume_test_client"), - app_(vsomeip::runtime::get()->create_application(name_)), - has_received_(false), - runner_(std::bind(&suspend_resume_test_client::run, this)) { - - } - - void run_test() { - - register_state_handler(); - register_message_handler(); - register_availability_handler(); - - start(); - - { - VSOMEIP_DEBUG << "Started."; - std::unique_lock its_lock(mutex_); - auto r = cv_.wait_for(its_lock, std::chrono::seconds(10)); - EXPECT_EQ(r, std::cv_status::no_timeout); - } - - toggle(); - - { - VSOMEIP_DEBUG << "Toggled."; - std::unique_lock its_lock(mutex_); - if (!has_received_) { - auto r = cv_.wait_for(its_lock, std::chrono::seconds(10)); - EXPECT_EQ(r, std::cv_status::no_timeout); - } - } - - send_suspend(); - - bool was_successful; - { - VSOMEIP_DEBUG << "Triggered suspend/resume."; - - // Wait for service to become availaber after suspend/resume. - std::unique_lock its_lock(mutex_); - auto r = cv_.wait_for(its_lock, std::chrono::seconds(10)); - EXPECT_EQ(r, std::cv_status::no_timeout); - - // Wait for initial event after suspend/resume. - r = cv_.wait_for(its_lock, std::chrono::seconds(10)); - EXPECT_EQ(r, std::cv_status::no_timeout); - - was_successful = (r == std::cv_status::no_timeout); - } - - if (was_successful) - send_stop(); - - stop(); - } - -private: - void register_state_handler() { - - app_->register_state_handler( - std::bind(&suspend_resume_test_client::on_state, this, std::placeholders::_1)); - } - - void register_availability_handler() { - - app_->register_availability_handler(TEST_SERVICE, TEST_INSTANCE, - std::bind(&suspend_resume_test_client::on_availability, this, - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - } - - void register_message_handler() { - - app_->register_message_handler(TEST_SERVICE, TEST_INSTANCE, TEST_EVENT, - std::bind(&suspend_resume_test_client::on_message, this, - std::placeholders::_1)); - } - - void start() { - - app_->init(); - cv_.notify_one(); - } - - void run() { - - { - std::unique_lock its_lock(mutex_); - cv_.wait(its_lock); - } - - app_->start(); - } - - void stop() { - - app_->stop(); - runner_.join(); - } - - void on_state(vsomeip::state_type_e _state) { - - VSOMEIP_DEBUG << __func__ << ": state=" - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "NOT registered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - app_->request_event(TEST_SERVICE, TEST_INSTANCE, TEST_EVENT, { TEST_EVENTGROUP }); - app_->request_service(TEST_SERVICE, TEST_INSTANCE); - } - } - - void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) { - - static bool is_available(false); - - if (_service == TEST_SERVICE && _instance == TEST_INSTANCE) { - - VSOMEIP_DEBUG << __func__ << ": Test service is " - << (_is_available ? "available." : "NOT available."); - - if (_is_available) - cv_.notify_one(); - else if (is_available) - has_received_ = false; - - is_available = _is_available; - } - } - - void on_message(const std::shared_ptr &_message) { - - if (_message->get_service() == TEST_SERVICE - && _message->get_instance() == TEST_INSTANCE - && _message->get_method() == TEST_EVENT) { - - VSOMEIP_DEBUG << __func__ << ": Received event."; - if (!has_received_) { - has_received_ = true; - cv_.notify_one(); - } - } - } - - void toggle() { - - app_->subscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, TEST_MAJOR); - std::this_thread::sleep_for(std::chrono::seconds(3)); - app_->unsubscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP); - app_->subscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, TEST_MAJOR); - std::this_thread::sleep_for(std::chrono::seconds(2)); - app_->unsubscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP); - app_->subscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, TEST_MAJOR); - - } - - - void send_suspend() { - - auto its_message = vsomeip::runtime::get()->create_request(false); - its_message->set_service(TEST_SERVICE); - its_message->set_instance(TEST_INSTANCE); - its_message->set_method(TEST_METHOD); - its_message->set_interface_version(TEST_MAJOR); - its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); - its_message->set_return_code(vsomeip::return_code_e::E_OK); - - vsomeip::byte_t its_data[] = { TEST_SUSPEND }; - auto its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data(its_data, sizeof(its_data)); - its_message->set_payload(its_payload); - - app_->send(its_message); - - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } - - void send_stop() { - - auto its_message = vsomeip::runtime::get()->create_request(false); - its_message->set_service(TEST_SERVICE); - its_message->set_instance(TEST_INSTANCE); - its_message->set_method(TEST_METHOD); - its_message->set_interface_version(TEST_MAJOR); - its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); - its_message->set_return_code(vsomeip::return_code_e::E_OK); - - vsomeip::byte_t its_data[] = { TEST_STOP }; - auto its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data(its_data, sizeof(its_data)); - its_message->set_payload(its_payload); - - app_->send(its_message); - - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } - -private: // members - std::string name_; - std::shared_ptr app_; - std::mutex mutex_; - std::condition_variable cv_; - bool has_received_; - std::thread runner_; -}; - -TEST(suspend_resume_test, fast) -{ - suspend_resume_test_client its_client; - its_client.run_test(); -} - -#ifndef _WIN32 -int main(int argc, char** argv) { - - ::testing::InitGoogleTest(&argc, argv); - - return RUN_ALL_TESTS(); -} -#endif // _WIN32 diff --git a/test/suspend_resume_tests/suspend_resume_test_master_starter.sh b/test/suspend_resume_tests/suspend_resume_test_master_starter.sh deleted file mode 100755 index 39a8d73..0000000 --- a/test/suspend_resume_tests/suspend_resume_test_master_starter.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/bash -# Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# Purpose: This script is needed to start the services with -# one command. This is necessary as ctest - which is used to run the -# tests - isn't able to start multiple binaries for one testcase. Therefore -# the testcase simply executes this script. This script then runs the services -# and checks that all exit successfully. - -FAIL=0 - -# Start the service -export VSOMEIP_APPLICATION_NAME=suspend_resume_test_service -export VSOMEIP_CONFIGURATION=suspend_resume_test_service.json - -# start daemon -../examples/routingmanagerd/./routingmanagerd & -PID_VSOMEIPD=$! - -# start the service -./suspend_resume_test_service $PID_VSOMEIPD & -PID_SERVICE=$! - -sleep 1 - -if [ ! -z "$USE_LXC_TEST" ]; then - echo "starting suspend_resume_test_slave_starter.sh on slave LXC with parameters $SLAVE_JSON_FILE" - ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test; ./suspend_resume_test_slave_starter.sh\"" & - echo "remote ssh job id: $!" -elif [ ! -z "$USE_DOCKER" ]; then - docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./suspend_resume_test_slave_starter.sh" & -elif [ ! -z "$JENKINS" ]; then - ssh -tt -i $PRV_KEY -o StrictHostKeyChecking=no jenkins@$IP_SLAVE "bash -ci \"set -m; cd $WS_ROOT/build/test; ./suspend_resume_test_slave_starter.sh\" >> $WS_ROOT/slave_test_output 2>&1" & - -else - cat < -#include -#include -#include - -#include - -#include -#include - -#include "suspend_resume_test.hpp" - -pid_t daemon_pid__; - -class suspend_resume_test_service { -public: - suspend_resume_test_service() - : name_("suspend_resume_test_service"), - app_(vsomeip::runtime::get()->create_application(name_)), - is_running_(true), - is_unblocked_(false), - runner_(std::bind(&suspend_resume_test_service::run, this)), - sr_runner_(std::bind(&suspend_resume_test_service::sr_run, this)) { - } - - void run_test() { - - register_state_handler(); - register_message_handler(); - register_subscription_handler(); - - start(); - - VSOMEIP_DEBUG << "Using daemon with pid=" << std::dec << daemon_pid__; - - { - std::unique_lock its_lock(mutex_); - auto r = cv_.wait_for(its_lock, std::chrono::seconds(30)); - EXPECT_EQ(r, std::cv_status::no_timeout); - } - - stop(); - } - -private: - void start() { - - app_->init(); - cv_.notify_one(); - } - - void stop() { - - is_running_ = false; - sr_cv_.notify_one(); - - app_->stop(); - - runner_.join(); - sr_runner_.join(); - } - - void run() { - - { - std::unique_lock its_lock(mutex_); - cv_.wait(its_lock); - } - - app_->start(); - } - - void sr_run() { - - while (is_running_) { - std::unique_lock its_lock(sr_mutex_); - sr_cv_.wait(its_lock); - - if (is_running_) { - VSOMEIP_DEBUG << "send kill SIGUSR1 to PID: " << std::dec << daemon_pid__; - kill(daemon_pid__, SIGUSR1); - std::this_thread::sleep_for(std::chrono::seconds(5)); - VSOMEIP_DEBUG << "send kill SIGUSR2 to PID: " << std::dec << daemon_pid__; - kill(daemon_pid__, SIGUSR2); - } - } - } - - void register_state_handler() { - - app_->register_state_handler( - std::bind(&suspend_resume_test_service::on_state, this, std::placeholders::_1)); - } - - void register_message_handler() { - - app_->register_message_handler(TEST_SERVICE, TEST_INSTANCE, TEST_METHOD, - std::bind(&suspend_resume_test_service::on_message, this, - std::placeholders::_1)); - } - - void register_subscription_handler() { - - app_->register_subscription_handler(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, - std::bind(&suspend_resume_test_service::on_subscribe, this, - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); - } - - void offer_service() { - app_->offer_event(TEST_SERVICE, TEST_INSTANCE, TEST_EVENT, { TEST_EVENTGROUP }, - vsomeip::event_type_e::ET_FIELD, - std::chrono::milliseconds::zero(), false, true, nullptr, - vsomeip::reliability_type_e::RT_UNRELIABLE); - - vsomeip::byte_t its_data[] = { 0x1, 0x2, 0x3 }; - auto its_payload = vsomeip::runtime::get()->create_payload(); - its_payload->set_data(its_data, sizeof(its_data)); - app_->notify(TEST_SERVICE, TEST_INSTANCE, TEST_EVENT, its_payload); - - app_->offer_service(TEST_SERVICE, TEST_INSTANCE, TEST_MAJOR, TEST_MINOR); - } - - // handler - void on_state(vsomeip::state_type_e _state) { - VSOMEIP_DEBUG << __func__ << ": state=" - << (_state == vsomeip::state_type_e::ST_REGISTERED ? - "registered." : "NOT registered."); - - if (_state == vsomeip::state_type_e::ST_REGISTERED) { - offer_service(); - } - } - - void on_message(const std::shared_ptr &_message) { - - VSOMEIP_DEBUG << __func__ << ": Received " - << std::hex << std::setw(4) << std::setfill('0') - << _message->get_service() - << std::hex << std::setw(4) << std::setfill('0') - << _message->get_instance() - << std::hex << std::setw(4) << std::setfill('0') - << _message->get_method(); - - if (_message->get_service() == TEST_SERVICE - && _message->get_instance() == TEST_INSTANCE - && _message->get_method() == TEST_METHOD) { - - if (_message->get_payload()->get_length() == 1) { - - vsomeip::byte_t its_control_byte(*_message->get_payload()->get_data()); - - switch (its_control_byte) { - case TEST_SUSPEND: - sr_cv_.notify_one(); - break; - case TEST_STOP: - cv_.notify_one(); - break; - default: - ; - } - } - } - } - - bool on_subscribe(vsomeip::client_t _client, - vsomeip::uid_t _uid, vsomeip::gid_t _gid, - bool _is_subscribe) { - - (void)_client; - (void)_uid; - (void)_gid; - - VSOMEIP_DEBUG << __func__ << ": is_subscribe=" << std::boolalpha << _is_subscribe; - if (!_is_subscribe) - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); - return (true); - } - -private: // members - std::string name_; - std::shared_ptr app_; - std::atomic is_running_; - bool is_unblocked_; - std::mutex mutex_; - std::condition_variable cv_; - std::mutex sr_mutex_; - std::condition_variable sr_cv_; - std::thread runner_; - std::thread sr_runner_; -}; - -TEST(suspend_resume_test, fast) -{ - suspend_resume_test_service its_service; - its_service.run_test(); -} - -#ifndef _WIN32 -int main(int argc, char** argv) { - - ::testing::InitGoogleTest(&argc, argv); - - daemon_pid__ = atoi(argv[1]); - - return RUN_ALL_TESTS(); -} -#endif // _WIN32 diff --git a/test/suspend_resume_tests/suspend_resume_test_slave_starter.sh b/test/suspend_resume_tests/suspend_resume_test_slave_starter.sh deleted file mode 100755 index 9cbf85d..0000000 --- a/test/suspend_resume_tests/suspend_resume_test_slave_starter.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash -# Copyright (C) 2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -FAIL=0 - -# Start the client -export VSOMEIP_APPLICATION_NAME=suspend_resume_test_client -export VSOMEIP_CONFIGURATION=suspend_resume_test_client.json -./suspend_resume_test_client & -PID_CLIENT=$! - -# Wait until all applications are finished -for job in $(jobs -p) -do - # Fail gets incremented if one of the binaries exits - # with a non-zero exit code - wait $job || ((FAIL+=1)) -done - -# Check if both exited successfully -if [ $FAIL -eq 0 ] -then - exit 0 -else - exit 1 -fi \ No newline at end of file diff --git a/test/unit_tests/CMakeLists.txt b/test/unit_tests/CMakeLists.txt new file mode 100644 index 0000000..ed63f6f --- /dev/null +++ b/test/unit_tests/CMakeLists.txt @@ -0,0 +1,29 @@ +# Copyright (C) 2015-2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +project ("unit_tests_bin" LANGUAGES CXX) + +file (GLOB SRCS main.cpp **/*.cpp ../common/utility.cpp) + +set(THREADS_PREFER_PTHREAD_FLAG ON) + +find_package(Threads REQUIRED) +find_package(Boost 1.55 COMPONENTS filesystem system REQUIRED) + +# ---------------------------------------------------------------------------- +# Executable and libraries to link +# ---------------------------------------------------------------------------- +add_executable (${PROJECT_NAME} ${SRCS} ) +target_link_libraries ( + ${PROJECT_NAME} + vsomeip3 + vsomeip3-cfg + Threads::Threads + ${Boost_LIBRARIES} + ${DL_LIBRARY} + gtest +) + +add_dependencies(build_unit_tests ${PROJECT_NAME}) diff --git a/test/unit_tests/main.cpp b/test/unit_tests/main.cpp new file mode 100644 index 0000000..3f704af --- /dev/null +++ b/test/unit_tests/main.cpp @@ -0,0 +1,16 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + // Test execution + int ret = RUN_ALL_TESTS(); + + // Exit + return ret; +} \ No newline at end of file diff --git a/test/unit_tests/security_tests/ut_check_credentials.cpp b/test/unit_tests/security_tests/ut_check_credentials.cpp new file mode 100644 index 0000000..7696892 --- /dev/null +++ b/test/unit_tests/security_tests/ut_check_credentials.cpp @@ -0,0 +1,122 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace { + vsomeip_v3::client_t client = 1; + vsomeip_v3::uid_t invalid_uid = 1; + vsomeip_v3::uid_t valid_uid = 4004201; + vsomeip_v3::gid_t invalid_gid = 1; + vsomeip_v3::gid_t valid_gid = 4004200; +} + +TEST(check_credentials_test, check_no_policies_loaded) { + + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + //no policies loaded -> check credentials will return false independent of the uid or gid + ASSERT_TRUE(its_manager->is_audit()); + ASSERT_FALSE(its_manager->is_enabled()); + + // create security clients + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + EXPECT_TRUE(its_manager->check_credentials(client, &its_sec_client_invalid)); +} + +TEST(check_credentials_test, check_policies_loaded) { + + std::unique_ptr its_manager( + new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + + utility::read_data(utility::get_all_files_in_dir( + utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + for (const auto& e : policy_elements) + its_manager->load(e, false); + + //check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + //the check_credentials_ and the policy_enabled_ variables should be set to true + ASSERT_FALSE(its_manager->is_audit()); + ASSERT_TRUE(its_manager->is_enabled()); + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + //invalid uid and gid -> the check must return false + EXPECT_FALSE(its_manager->check_credentials(client, &its_sec_client_invalid)); + + //invalid uid and valid gid -> the check must return false + EXPECT_FALSE(its_manager->check_credentials(client, &its_sec_client_invalid)); + + //valid uid and invalid gid -> the check must return false + EXPECT_FALSE(its_manager->check_credentials(client, &its_sec_client_invalid)); + + //valid uid and gid -> the check must return true + EXPECT_TRUE(its_manager->check_credentials(client, &its_sec_client_valid)); +} + +// check_credentials with policies loaded but in audit mode +// vsomeip's security implementation can be put in a so called 'Audit Mode' where +// all security violations will be logged but allowed. +// To activate the 'Audit Mode' the 'security' object has to be included in the +// json file but the 'check_credentials' switch has to be set to false. +TEST(check_credentials_test, check_policies_loaded_in_audit_mode) { + + std::unique_ptr its_manager( + new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir( + utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + //the check_credentials_ variable is force to be false + utility::force_check_credentials(policy_elements, "false"); + + for (const auto& e : policy_elements) + its_manager->load(e, false); + + //check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + //expect check_credentials_ false and the policy_enabled_ true + ASSERT_TRUE(its_manager->is_audit()); + ASSERT_TRUE(its_manager->is_enabled()); + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + vsomeip_sec_client_t its_sec_client_invalid_valid = utility::create_uds_client(invalid_uid, valid_gid); + vsomeip_sec_client_t its_sec_client_valid_invalid = utility::create_uds_client(valid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + // is expected check_credentials method always return true + //invalid uid and gid + EXPECT_TRUE(its_manager->check_credentials(client, &its_sec_client_invalid)); + + //invalid uid and valid gid + EXPECT_TRUE(its_manager->check_credentials(client, &its_sec_client_invalid_valid)); + + //valid uid and invalid gid + EXPECT_TRUE(its_manager->check_credentials(client, &its_sec_client_valid_invalid)); + + //valid uid and gid + EXPECT_TRUE(its_manager->check_credentials(client, &its_sec_client_valid)); +} \ No newline at end of file diff --git a/test/unit_tests/security_tests/ut_check_routing_credentials.cpp b/test/unit_tests/security_tests/ut_check_routing_credentials.cpp new file mode 100644 index 0000000..ef9040d --- /dev/null +++ b/test/unit_tests/security_tests/ut_check_routing_credentials.cpp @@ -0,0 +1,85 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace { +vsomeip_v3::uid_t invalid_uid = 1; +vsomeip_v3::uid_t valid_uid = 4003017; +vsomeip_v3::gid_t invalid_gid = 1; +vsomeip_v3::gid_t valid_gid = 5002; +} + +TEST(check_routing_credentials, check_policies_loaded) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + for (const auto& e : policy_elements) + security->load(e, false); + + //check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_valid_uid_invalid_gid = utility::create_uds_client(valid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_invalid_uid_valid_gid = utility::create_uds_client(invalid_uid, valid_gid); + + //valid uid and gid -> the check must return true + EXPECT_TRUE(security->check_routing_credentials(&its_sec_client_valid)); + + //invalid gid and valid gid -> the check must return false + EXPECT_FALSE(security->check_routing_credentials(&its_sec_client_valid_uid_invalid_gid)); + + //invalid uid and valid gid -> the check must return false + EXPECT_FALSE(security->check_routing_credentials(&its_sec_client_invalid_uid_valid_gid)); + + //invalid uid and gid -> the check must return false + EXPECT_FALSE(security->check_routing_credentials(&its_sec_client_invalid)); +} + +// check_routing_credentials with policies loaded in lazy mode +// vsomeip's security implementation can be put in a so called 'Audit Mode' where +// all security violations will be logged but allowed. +// To activate the 'Audit Mode' the 'security' object has to be included in the +// json file but the 'check_routing_credentials' switch has to be set to false. +TEST(check_routing_credentials, check_policies_loaded_lazy_load) { + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + // load policies in lazy mode so that check_routing_credentials is false + for (const auto& e : policy_elements) + security->load(e, true); + + //check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(valid_uid, valid_gid); + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_valid_uid_invalid_gid = utility::create_uds_client(valid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_invalid_uid_valid_gid = utility::create_uds_client(invalid_uid, valid_gid); + + //expect check_routing_credentials_ false so method always returns true + EXPECT_TRUE(security->check_routing_credentials(&its_sec_client_valid)); + EXPECT_TRUE(security->check_routing_credentials(&its_sec_client_valid_uid_invalid_gid)); + EXPECT_TRUE(security->check_routing_credentials(&its_sec_client_invalid_uid_valid_gid)); + EXPECT_TRUE(security->check_routing_credentials(&its_sec_client_invalid)); +} diff --git a/test/unit_tests/security_tests/ut_get_client_to_sec_client_mapping.cpp b/test/unit_tests/security_tests/ut_get_client_to_sec_client_mapping.cpp new file mode 100644 index 0000000..efcb826 --- /dev/null +++ b/test/unit_tests/security_tests/ut_get_client_to_sec_client_mapping.cpp @@ -0,0 +1,62 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace { +vsomeip_v3::client_t client = 10; +vsomeip_v3::client_t alternate_client = 11; +vsomeip_v3::uid_t uid_1 = 4003030; +vsomeip_v3::gid_t gid_1 = 4003032; +vsomeip_v3::uid_t uid_2 = 1; +vsomeip_v3::gid_t gid_2 = 1; +vsomeip_v3::uid_t uid_3 = 2; +vsomeip_v3::gid_t gid_3 = 2; +} + +TEST(get_client_to_sec_client_mapping, test) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid_1 = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_uid_gid_2 = utility::create_uds_client(uid_2, gid_2); + vsomeip_sec_client_t its_sec_client_uid_gid_3 = utility::create_uds_client(uid_3, gid_3); + + // Client and uid_gid should not be stored yet. + EXPECT_FALSE(security->get_client_to_sec_client_mapping(client, its_sec_client_uid_gid_1)); + + // Add client and uid_gid mappings. + security->store_client_to_sec_client_mapping(client, &its_sec_client_uid_gid_1); + + // uid_gid and uid_gid_2 should not be equal. + EXPECT_NE(its_sec_client_uid_gid_1.client.uds_client.group, its_sec_client_uid_gid_2.client.uds_client.group); + EXPECT_NE(its_sec_client_uid_gid_1.client.uds_client.user, its_sec_client_uid_gid_2.client.uds_client.user); + + // Client and uid_gid mapping should be returned. + EXPECT_TRUE(security->get_client_to_sec_client_mapping(client, its_sec_client_uid_gid_2)); + + // uid_gid and uid_gid_2 should be equal if get was successful. + EXPECT_EQ(its_sec_client_uid_gid_1.client.uds_client.group, its_sec_client_uid_gid_2.client.uds_client.group); + EXPECT_EQ(its_sec_client_uid_gid_1.client.uds_client.user, its_sec_client_uid_gid_2.client.uds_client.user); + + // Alternate_client is not stored, this should return false. + EXPECT_FALSE(security->get_client_to_sec_client_mapping(alternate_client, its_sec_client_uid_gid_1)); + + // Add alternate client and uid_gid mappings. + security->store_client_to_sec_client_mapping(alternate_client, &its_sec_client_uid_gid_1); + + // uid_gid and uid_gid_3 should not be equal. + EXPECT_NE(its_sec_client_uid_gid_1.client.uds_client.group, its_sec_client_uid_gid_3.client.uds_client.group); + EXPECT_NE(its_sec_client_uid_gid_1.client.uds_client.user, its_sec_client_uid_gid_3.client.uds_client.user); + + // Alternate client and uid_gid mapping should be returned. + EXPECT_TRUE(security->get_client_to_sec_client_mapping(alternate_client, its_sec_client_uid_gid_3)); + + // uid_gid and uid_gid_3 should be equal if get was successful. + EXPECT_EQ(its_sec_client_uid_gid_1.client.uds_client.group, its_sec_client_uid_gid_3.client.uds_client.group); + EXPECT_EQ(its_sec_client_uid_gid_1.client.uds_client.user, its_sec_client_uid_gid_3.client.uds_client.user); + } diff --git a/test/unit_tests/security_tests/ut_get_clients.cpp b/test/unit_tests/security_tests/ut_get_clients.cpp new file mode 100644 index 0000000..093200c --- /dev/null +++ b/test/unit_tests/security_tests/ut_get_clients.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace { +std::unordered_set clients; +std::unordered_set local_clients; +vsomeip_v3::client_t client_1 = 10; +vsomeip_v3::client_t client_2 = 11; +vsomeip_v3::client_t client_3 = 12; +vsomeip_v3::uid_t uid = 4003030; +vsomeip_v3::gid_t gid = 4003032; +} + +TEST(get_clients, test) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client_uid_gid = utility::create_uds_client(uid, gid); + + // Local_clients has now one client(10). + local_clients.insert(client_1); + + // Clients should be empty. + EXPECT_TRUE(clients.empty()); + + // Should do nothing because there is not a client to uid_gid mapping yet. + security->get_clients(uid, gid, clients); + + // clients should still be empty. + EXPECT_TRUE(clients.empty()); + + // Stores client to uid_gid_mapping. + security->store_client_to_sec_client_mapping(client_1, &its_sec_client_uid_gid); + security->get_clients(uid, gid, clients); + + // Clients and local_clients should be equal and have the same client(10). + EXPECT_EQ(clients, local_clients); + + // Repeat with two more clients. + security->store_client_to_sec_client_mapping(client_2, &its_sec_client_uid_gid); + security->store_client_to_sec_client_mapping(client_3, &its_sec_client_uid_gid); + + local_clients.insert(client_2); + local_clients.insert(client_3); + + security->get_clients(uid, gid, clients); + + // Clients and local_clients should be equal and have the same 3 clients(10,11,12). + EXPECT_EQ(clients, local_clients); +} diff --git a/test/unit_tests/security_tests/ut_get_sec_client_to_clients_mapping.cpp b/test/unit_tests/security_tests/ut_get_sec_client_to_clients_mapping.cpp new file mode 100644 index 0000000..96ae416 --- /dev/null +++ b/test/unit_tests/security_tests/ut_get_sec_client_to_clients_mapping.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace{ +vsomeip_v3::client_t client = 10; +vsomeip_v3::uid_t uid_1 = 4003030; +vsomeip_v3::gid_t gid_1 = 4003032; +vsomeip_v3::uid_t uid_2 = 1; +vsomeip_v3::gid_t gid_2 = 1; +} + +TEST(get_sec_client_to_clients_mapping, test) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + std::set clients_1; + clients_1.insert(client); + + vsomeip_sec_client_t its_sec_client_uid_gid = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_uid_gid_alternate = utility::create_uds_client(uid_2, gid_2); + + // Client and uid_gid should not be stored yet. + EXPECT_FALSE(security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid, clients_1)); + + // Add client and uid_gid mappings. + security->store_sec_client_to_client_mapping(&its_sec_client_uid_gid, client); + + std::set clients_2; + + // Clients and clients_2 should not be equal. + EXPECT_NE(clients_1, clients_2); + + // Client and uid_gid mapping should be returned. + EXPECT_TRUE(security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid, clients_2)); + + // Clients and clients_2 should be equal if get was successful. + EXPECT_EQ(clients_1, clients_2); + + // Alternate_uid_gid is not stored, this should return false. + EXPECT_FALSE(security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid_alternate, clients_1)); + + // Add alternate client and uid_gid mappings. + security->store_sec_client_to_client_mapping(&its_sec_client_uid_gid_alternate, client); + + std::set clients_3; + + // Clients and clients_3 should not be equal. + EXPECT_NE(clients_1, clients_3); + + // Alternate client and uid_gid mapping should be returned. + EXPECT_TRUE(security->get_sec_client_to_clients_mapping(&its_sec_client_uid_gid_alternate, clients_3)); + + // Clients and clients_3 should be equal if get was successful. + EXPECT_EQ(clients_1, clients_3); +} diff --git a/test/unit_tests/security_tests/ut_is_client_allowed.cpp b/test/unit_tests/security_tests/ut_is_client_allowed.cpp new file mode 100644 index 0000000..ab65153 --- /dev/null +++ b/test/unit_tests/security_tests/ut_is_client_allowed.cpp @@ -0,0 +1,149 @@ +#include +#include "gtest/gtest.h" +#include "../../common/utility.hpp" + +namespace { + vsomeip_v3::uid_t uid_1 = 4003031; + vsomeip_v3::gid_t gid_1 = 4003031; + vsomeip_v3::service_t service_1 = 0xf913; + + vsomeip_v3::service_t service_2 = 0x41; // service not defined in policies + + vsomeip_v3::instance_t instance = 0x03; + vsomeip_v3::instance_t instance_2 = 0x04; + vsomeip_v3::method_t method = 0x04; + vsomeip_v3::method_t method_2 = 0x05; + + vsomeip_v3::gid_t invalid_uid = 1; + vsomeip_v3::gid_t invalid_gid = 1; + vsomeip_v3::uid_t ANY_UID = 0xFFFFFFFF; + vsomeip_v3::gid_t ANY_GID = 0xFFFFFFFF; + + vsomeip_v3::gid_t deny_uid = 9999; + vsomeip_v3::gid_t deny_gid = 9999; + vsomeip_v3::service_t deny_service = 0x40; +} + +TEST(is_client_allowed_test, check_no_policies_loaded) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + //no policies loaded -> is_client_allowed must return true + ASSERT_FALSE(its_manager->is_enabled()); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_invalid, service_1, instance, method)); +} + +TEST(is_client_allowed_test, check_policies_loaded) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + //check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + // check if the policies are loaded and check_credentials_ variable are true + ASSERT_TRUE(its_manager->is_enabled()); + ASSERT_FALSE(its_manager->is_audit()); + + // create security clients + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_invalid_uid = utility::create_uds_client(invalid_uid, gid_1); + vsomeip_sec_client_t its_sec_client_invalid_gid = utility::create_uds_client(uid_1, invalid_gid); + vsomeip_sec_client_t its_sec_client_any = utility::create_uds_client(ANY_UID, ANY_GID); + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + + //valid credential for valid service / istance / method + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance, method)); + + // test is_client_allowed_cache_, request with the same credentials and service / instance / method + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance, method)); + + // test is_client_allowed_cache_, request with the same credentials and service but with a different instance or method + // is_client_allowed return true because it's define ANY_INSTANCE and ANY_METHOD in the policy + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance_2, method)); + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance, method_2)); + + //invalid credential for the service / istance / method + EXPECT_FALSE(its_manager->is_client_allowed(&its_sec_client_invalid_uid, service_1, instance, method)); + EXPECT_FALSE(its_manager->is_client_allowed(&its_sec_client_invalid_gid, service_1, instance, method)); + + //ANY_UID and ANY_GID + EXPECT_FALSE(its_manager->is_client_allowed(&its_sec_client_any, service_1, instance, method)); + + // test deny client + // deny client with credentials for the service + EXPECT_FALSE(its_manager->is_client_allowed(&its_sec_client_deny, deny_service, instance, method)); + // credencials exists in deny policy, but not for that service + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_deny, service_2, instance, method)); +} + + +// is_client_allowed with policies loaded but in audit mode +// vsomeip's security implementation can be put in a so called 'Audit Mode' where +// all security violations will be logged but allowed. +// To activate the 'Audit Mode' the 'security' object has to be included in the +// json file but the 'check_credentials' switch has to be set to false. + TEST(is_client_allowed_test, check_policies_loaded_in_audit_mode) { + std::unique_ptr its_manager(new vsomeip_v3::policy_manager_impl); + + //force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + //check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + utility::force_check_credentials(policy_elements, "false"); + + for (const auto& e : policy_elements) { + its_manager->load(e, false); + } + + // check if the policies are loaded and check_credentials_ variable are false + ASSERT_TRUE(its_manager->is_enabled()); + ASSERT_TRUE(its_manager->is_audit()); + + // create security clients + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_invalid_uid = utility::create_uds_client(invalid_uid, gid_1); + vsomeip_sec_client_t its_sec_client_invalid_gid = utility::create_uds_client(uid_1, invalid_gid); + vsomeip_sec_client_t its_sec_client_any = utility::create_uds_client(ANY_UID, ANY_GID); + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + + // is expected is_client_allowed method always returns true + // valid credential for valid service / istance / method + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance, method)); + + // test is_client_allowed_cache_, request with the same credentials and service / instance / method + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance, method)); + + // test is_client_allowed_cache_, request with the same credentials and service but with a different instance or method + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance_2, method)); + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client, service_1, instance, method_2)); + + // invalid credential for the service / istance / method + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_invalid_uid, service_1, instance, method)); + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_invalid_gid, service_1, instance, method)); + + // ANY_UID and ANY_GID + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_any, service_1, instance, method)); + + // test deny client + // deny client with credentials for the service + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_deny, deny_service, instance, method)); + // credencials exists in deny policy, but not for that service + EXPECT_TRUE(its_manager->is_client_allowed(&its_sec_client_deny, service_2, instance, method)); +} \ No newline at end of file diff --git a/test/unit_tests/security_tests/ut_is_offer_allowed.cpp b/test/unit_tests/security_tests/ut_is_offer_allowed.cpp new file mode 100644 index 0000000..f60d4ed --- /dev/null +++ b/test/unit_tests/security_tests/ut_is_offer_allowed.cpp @@ -0,0 +1,153 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" +namespace{ + +vsomeip_v3::uid_t uid_1 = 4003016; +vsomeip_v3::gid_t gid_1 = 4003016; +vsomeip_v3::service_t service_1 = 0xf8c2; + +vsomeip_v3::service_t deny_service = 0x40; + +vsomeip_v3::instance_t instance = 0x03; +vsomeip_v3::instance_t any_instance = 0xfffe; + +vsomeip_v3::uid_t invalid_uid = 1; +vsomeip_v3::gid_t invalid_gid = 1; +vsomeip_v3::uid_t ANY_UID = 0xFFFFFFFF; +vsomeip_v3::gid_t ANY_GID = 0xFFFFFFFF; + +vsomeip_v3::gid_t deny_uid = 9000; +vsomeip_v3::gid_t deny_gid = 9000; +} + +TEST(is_offer_allowed, check_no_policies_loaded) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + ASSERT_FALSE(security->is_enabled()); + + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + + // no policies loaded -> is_offer_allowed must return true + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_invalid, service_1, instance)); +} + +TEST(is_offer_allowed, check_policies_loaded) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + // check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + for (const auto &e : policy_elements) + { + security->load(e, false); + } + + // check if the policies are loaded and check_credentials_ variable are true + ASSERT_TRUE(security->is_enabled()); + ASSERT_FALSE(security->is_audit()); + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_valid_uid_invalid_gid = utility::create_uds_client(uid_1, invalid_gid); + vsomeip_sec_client_t its_sec_client_invalid_uid_valid_gid = utility::create_uds_client(invalid_uid, gid_1); + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + vsomeip_sec_client_t its_sec_client_any = utility::create_uds_client(ANY_UID, ANY_GID); + + // valid credential for valid service / instance + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_valid, service_1, instance)); + + // request with the same credentials and service but with a different instance + // is_offer_allowed return true because it's define ANY_INSTANCE in the policy + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_valid, service_1, any_instance)); + + // invalid credential for the service / instance + EXPECT_FALSE(security->is_offer_allowed(&its_sec_client_invalid_uid_valid_gid, service_1, instance)); + EXPECT_FALSE(security->is_offer_allowed(&its_sec_client_valid_uid_invalid_gid, service_1, instance)); + EXPECT_FALSE(security->is_offer_allowed(&its_sec_client_invalid, service_1, instance)); + + // test deny offer + // deny client with credentials for the service + EXPECT_FALSE(security->is_offer_allowed(&its_sec_client_deny, deny_service, instance)); + // credentials exists in deny policy, but not for that service + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_deny, service_1, instance)); + + // ANY_UID and ANY_GID + EXPECT_FALSE(security->is_offer_allowed(&its_sec_client_any, service_1, instance)); +} + +// is_offer_allowed with policies loaded but in audit mode +// vsomeip's security implementation can be put in a so called 'Audit Mode' where +// all security violations will be logged but allowed. +// To activate the 'Audit Mode' the 'security' object has to be included in the +// json file but the 'check_credentials' switch has to be set to false. + +TEST(is_offer_allowed, check_policies_loaded_in_audit_mode) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // create security clients + vsomeip_sec_client_t its_sec_client_valid = utility::create_uds_client(uid_1, gid_1); + vsomeip_sec_client_t its_sec_client_invalid = utility::create_uds_client(invalid_uid, invalid_gid); + vsomeip_sec_client_t its_sec_client_valid_uid_invalid_gid = utility::create_uds_client(uid_1, invalid_gid); + vsomeip_sec_client_t its_sec_client_invalid_uid_valid_gid = utility::create_uds_client(invalid_uid, gid_1); + vsomeip_sec_client_t its_sec_client_deny = utility::create_uds_client(deny_uid, deny_gid); + vsomeip_sec_client_t its_sec_client_any = utility::create_uds_client(ANY_UID, ANY_GID); + + // force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), policy_elements, its_failed); + + // check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + utility::force_check_credentials(policy_elements, "false"); + + for (const auto &e : policy_elements) + { + security->load(e, false); + } + + // check if the policies are loaded and check_credentials_ variable are true + ASSERT_TRUE(security->is_enabled()); + ASSERT_TRUE(security->is_audit()); + + // valid credential for valid service / instance + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_valid, service_1, instance)); + + // request with the same credentials and service but with a different instance + // is_offer_allowed return true because it's define ANY_INSTANCE in the policy + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_valid, service_1, any_instance)); + + // invalid credential for the service / instance + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_invalid_uid_valid_gid, service_1, instance)); + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_valid_uid_invalid_gid, service_1, instance)); + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_invalid, service_1, instance)); + + // test deny offer + // deny client with credentials for the service + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_deny, deny_service, instance)); + // credentials exists in deny policy, but not for that service + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_deny, service_1, instance)); + + // ANY_UID and ANY_GID + EXPECT_TRUE(security->is_offer_allowed(&its_sec_client_any, service_1, instance)); +} diff --git a/test/unit_tests/security_tests/ut_is_policy_update_allowed.cpp b/test/unit_tests/security_tests/ut_is_policy_update_allowed.cpp new file mode 100644 index 0000000..20c6ba5 --- /dev/null +++ b/test/unit_tests/security_tests/ut_is_policy_update_allowed.cpp @@ -0,0 +1,221 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include "../../common/utility.hpp" + +namespace { +std::string configuration_file { "/vsomeip/0_0/vsomeip_security.json" }; + +vsomeip_v3::uid_t valid_uid { 0 }; +vsomeip_v3::uid_t invalid_uid { 1234567 }; + +vsomeip_v3::gid_t valid_gid { 0 }; + +vsomeip_v3::service_t valid_service { 0xf913 }; +vsomeip_v3::service_t invalid_service { 0x41 }; +} + +TEST(is_policy_update_allowed, check_whitelist_disabled) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the configuration into the security. + ASSERT_GT(policy_elements.size(), 0) << "Failed to fetch policy elements!"; + const bool check_whitelist { false }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + // NO REQUESTS IN POLICY ---------------------------------------------------------------------// + + EXPECT_TRUE(security->is_policy_update_allowed(invalid_uid, policy)) + << "Failed to allow policy update with invalid user id when check_whitelist is " + "disabled!"; + + EXPECT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "Failed to allow policy update with valid user id when check_whitelist is " + "disabled!"; + + // ONLY VALID REQUESTS IN POLICY -------------------------------------------------------------// + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map> + its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + valid_service, valid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + EXPECT_TRUE(security->is_policy_update_allowed(invalid_uid, policy)) + << "Failed to allow policy update with invalid user id and valid request when " + "check_whitelist is disabled!"; + + EXPECT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "Failed to allow policy update with valid user id and valid request when " + "check_whitelist is disabled!"; + + // INVALID REQUESTS IN POLICY ----------------------------------------------------------------// + + // Add a invalid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + invalid_service, invalid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + EXPECT_TRUE(security->is_policy_update_allowed(invalid_uid, policy)) + << "Failed to allow policy update with invalid user id and invalid request when " + "check_whitelist is disabled!"; + + EXPECT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "Failed to allow policy update with valid user id and invalid request when " + "check_whitelist is disabled!"; +} + +TEST(is_policy_update_allowed, check_whitelist_enabled) +{ + // Test object. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the policy into the security. + ASSERT_GT(policy_elements.size(), 0) << "Failed to fetch policy elements!"; + const bool check_whitelist { true }; + utility::add_security_whitelist(policy_elements.at(0), check_whitelist); + security->load(policy_elements.at(0), false); + + // Create policy credentials. + boost::icl::discrete_interval its_uids(valid_uid, valid_uid); + boost::icl::interval_set its_gids; + its_gids.insert(boost::icl::interval::closed(valid_gid, valid_gid)); + + // Create a policy. + std::shared_ptr policy(std::make_shared()); + policy->credentials_ += std::make_pair(its_uids, its_gids); + policy->allow_who_ = true; + policy->allow_what_ = true; + + // NO REQUESTS IN POLICY ---------------------------------------------------------------------// + + EXPECT_FALSE(security->is_policy_update_allowed(invalid_uid, policy)) + << "Failed to deny policy update with invalid user id!"; + + EXPECT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "Failed to allow policy update with valid user id!"; + + // ONLY VALID REQUESTS IN POLICY -------------------------------------------------------------// + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map> + its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add valid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + valid_service, valid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + EXPECT_FALSE(security->is_policy_update_allowed(invalid_uid, policy)) + << "Failed to deny policy update with invalid user id and valid request!"; + + EXPECT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "Failed to allow policy update with valid user id and valid request!"; + + // INVALID REQUESTS IN POLICY ----------------------------------------------------------------// + + // Add invalid request to the policy. + policy->requests_ += std::make_pair( + boost::icl::discrete_interval( + invalid_service, invalid_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + EXPECT_FALSE(security->is_policy_update_allowed(invalid_uid, policy)) + << "Failed to deny policy update with invalid user id and invalid request!"; + + EXPECT_FALSE(security->is_policy_update_allowed(valid_uid, policy)) + << "Failed to deny policy update with valid user id and invalid request!"; +} + +TEST(is_policy_update_allowed, null_policy) +{ + // Test objects. + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + std::shared_ptr policy = nullptr; + + // NO POLICIES LOADED ------------------------------------------------------------------------// + + ASSERT_EXIT((security->is_policy_update_allowed(0, policy), exit(0)), + testing::ExitedWithCode(0), ".*") + << "Could not handle a nullptr when no policies are loaded!"; + + EXPECT_TRUE(security->is_policy_update_allowed(0, policy)) + << "Denied update of policy when security whitelist is not loaded!"; + + // LOADED POLICY W/O SECURITY WHITELIST ------------------------------------------------------// + + // Get some configurations. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Load the policy into the security. + ASSERT_GT(policy_elements.size(), 0) << "Failed to fetch policy elements!"; + security->load(policy_elements.at(0), false); + + ASSERT_EXIT((security->is_policy_update_allowed(0, policy), exit(0)), + testing::ExitedWithCode(0), ".*") + << "Could not handle a nullptr when a policy without a security whitelist was loaded!"; + + EXPECT_TRUE(security->is_policy_update_allowed(0, policy)) + << "Denied update of policy when security whitelist is not loaded!"; + + // LOADED POLICY W/ SECURITY WHITELIST -------------------------------------------------------// + + // Add a security whitelist to the policy. + + utility::add_security_whitelist(policy_elements.at(0), true); + + security->load(policy_elements.at(0), false); + + ASSERT_EXIT((security->is_policy_update_allowed(0, policy), exit(0)), + testing::ExitedWithCode(0), ".*") + << "Could not handle a nullptr when a policy with a security whitelist was loaded!"; + + EXPECT_FALSE(security->is_policy_update_allowed(0, policy)) + << "Allowed update of invalid policy!"; +} diff --git a/test/unit_tests/security_tests/ut_load_policies.cpp b/test/unit_tests/security_tests/ut_load_policies.cpp new file mode 100644 index 0000000..83d7b3a --- /dev/null +++ b/test/unit_tests/security_tests/ut_load_policies.cpp @@ -0,0 +1,100 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace { +std::string configuration_file { "/vsomeip/0_0/vsomeip_security.json" }; +vsomeip_v3::uid_t valid_uid = 4002200; +vsomeip_v3::gid_t valid_gid = 4003014; +} + +// Since this set of tests check a private method, there is the need to indirectly change the +// parameters used by load_policies, and check its changes using other methods. +// The remove_security_policy method checks if there is any loaded policy. +// The is_audit method checks the check_credentials value. +// No test was created for allow_remote_clients because it was inacessible. + +TEST(load_policies, any_policies_present) +{ + // LOADED POLICIES --------------------------------------------------------------------------// + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Check if the load worked. + ASSERT_EQ(its_failed.size(), 0); + + // Using load function to indirectly call load_policies. + security->load(policy_elements.at(0)); + + // Check that the policies were loaded from the file by trying to remove one of the loaded + // policies. + // If the policy is present, remove_security_policy returns true. + ASSERT_TRUE(security->remove_security_policy(valid_uid,valid_gid)) + << "Trying to remove a policy that is supposed to exist, but doesn't"; + + // POLICIES NOT LOADED -----------------------------------------------------------------------// + // Remove all the policies from the file. + policy_elements.at(0).tree_.get_child("security").erase("policies"); + + // Using load function to indirectly call load_policies. + security->load(policy_elements.at(0)); + + // Check that no policies were loaded. + ASSERT_FALSE(security->remove_security_policy(valid_uid,valid_gid)) + << "Trying to remove a policy should not exist, but it exists"; +} + +TEST(load_policies, check_credentials) +{ + // CHECK CREDENTIALS NOT SET -----------------------------------------------------------------// + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies without the check credentials value set. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Check if the load worked. + ASSERT_EQ(its_failed.size(), 0); + + security->load(policy_elements.at(0)); + + // Check that the check_credentials value was not set, using the is_audit method. + ASSERT_TRUE(security->is_audit()) + << "Check credentials value should be false when no value is loaded"; + + // CHECK CREDENTIALS SET TRUE ----------------------------------------------------------------// + + // Load the check credentials value as false. + bool check_credentials_value {true}; + policy_elements.at(0).tree_.add("security.check_credentials", check_credentials_value); + security->load(policy_elements.at(0)); + + // Check that the check_credentials flag was not set internally, using the is_audit method. + ASSERT_FALSE(security->is_audit()) + << "Check credentials flag should be true when the check_credential value is loaded as" + "true"; + + // CHECK CREDENTIALS SET FALSE ---------------------------------------------------------------// + + // Load the check credentials value as false. + check_credentials_value = false; + policy_elements.at(0).tree_.put("security.check_credentials", check_credentials_value); + security->load(policy_elements.at(0)); + + // Check that the check_credentials flag was set false, using the is_audit method. + ASSERT_TRUE(security->is_audit()) + << "Check credentials flag should be false when the check_credential value is loaded as" + "false"; +} diff --git a/test/unit_tests/security_tests/ut_load_security_update_whitelist.cpp b/test/unit_tests/security_tests/ut_load_security_update_whitelist.cpp new file mode 100644 index 0000000..5fcd5da --- /dev/null +++ b/test/unit_tests/security_tests/ut_load_security_update_whitelist.cpp @@ -0,0 +1,218 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace { +std::string configuration_file { "/vsomeip/0_0/vsomeip_security.json" }; +vsomeip_v3::service_t valid_service_id = 0xf91f; +vsomeip_v3::service_t invalid_service_id = 0xf923; +vsomeip_v3::uid_t valid_uid = 4017205; +vsomeip_v3::uid_t invalid_uid = 111111; +} + +// Since this set of tests check a private method, there is the need to indirectly change the +// parameters used by load_security_update_whitelist, and check its changes using other methods. +// The is_policy_removal_allowed method checks if a selected uid is present in the whitelist. +// The is_policy_update_allowed method checks if a selected service_id is present in the whitelist. + +TEST(load_security_update_whitelist, check_uids) +{ + // LOADED POLICY W/O UIDS ON SECURITY WHITELIST ---------------------------------------------// + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Check if the load worked. + ASSERT_EQ(its_failed.size(), 0); + + std::vector services; + utility::get_policy_services(policy_elements.at(0), services); + + // Add a security whitelist with an empty list of user uids. + std::vector user_ids; + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + security->load(policy_elements.at(0)); + + // Check that the valid and invalid uids are not present in the whitelist by calling a method + // that verifies that condition. + ASSERT_FALSE(security->is_policy_removal_allowed(valid_uid)) + << "The whitelist unexpectedly holds a valid uid"; + + ASSERT_FALSE(security->is_policy_removal_allowed(invalid_uid)) + << "The whitelist unexpectedly holds an invalid uid"; + + // LOADED POLICY WITH UIDS ON SECURITY WHITELIST ---------------------------------------------// + utility::get_policy_uids(policy_elements.at(0), user_ids); + + // Add a security whitelist with list of user uids loaded. + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + security->load(policy_elements.at(0)); + + // Check that the valid and invalid uids are not present in the whitelist by calling a method + // that verifies that condition. + ASSERT_TRUE(security->is_policy_removal_allowed(valid_uid)) + << "The whitelist expected to hold a valid uid"; + + ASSERT_FALSE(security->is_policy_removal_allowed(invalid_uid)) + << "The whitelist unexpectedly holds an invalid uid"; +} + +TEST(load_security_update_whitelist, check_service_ids) +{ + // LOADED POLICY W/O SERVICE IDS ON SECURITY WHITELIST -------------------------------------// + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Check if the load worked. + ASSERT_EQ(its_failed.size(), 0); + + std::vector user_ids; + utility::get_policy_uids(policy_elements.at(0), user_ids); + + // Add a security whitelist with an empty list of service ids. + std::vector services; + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + // Using load function to indirectly call load_security_update_whitelist. + security->load(policy_elements.at(0)); + + std::shared_ptr policy(std::make_shared()); + + vsomeip::service_t its_service(valid_service_id); + vsomeip::service_t its_invalid_service(invalid_service_id); + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map> + its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy + policy->requests_ += + std::make_pair(boost::icl::discrete_interval( + its_service, its_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + // Check its presence using the is_policy_update_allowed method. + ASSERT_FALSE(security->is_policy_update_allowed(valid_uid, policy)) + << "The whitelist unexpectedly holds a valid service_id"; + + // Add an invalid request to the policy + policy->requests_ += std::make_pair(boost::icl::discrete_interval( + its_invalid_service, its_invalid_service, + boost::icl::interval_bounds::closed()), + its_instances_methods); + + // Check its presence using the is_policy_update_allowed method. + ASSERT_FALSE(security->is_policy_update_allowed(valid_uid, policy)) + << "The whitelist unexpectedly holds an invalid service_id"; + + // LOADED POLICY WITH SERVICE IDS ON SECURITY WHITELIST --------------------------------------// + utility::get_policy_services(policy_elements.at(0), services); + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, true); + + security->load(policy_elements.at(0)); + + // Reset the policies pointer to add a correct serviceid and an incorrect one. + policy->requests_.clear(); + + // Add a valid request to the policy. + policy->requests_ += + std::make_pair(boost::icl::discrete_interval( + its_service, its_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + // Check its presence using the is_policy_update_allowed method. + ASSERT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "The whitelist expected to hold a valid service_id"; + + // Add an invalid request to the policy. + policy->requests_ += std::make_pair(boost::icl::discrete_interval( + its_invalid_service, its_invalid_service, + boost::icl::interval_bounds::closed()), + its_instances_methods); + + // Check its presence using the is_policy_update_allowed method. + ASSERT_FALSE(security->is_policy_update_allowed(invalid_uid, policy)) + << "The whitelist unexpectedly holds an invalid service_id"; +} + +TEST(load_security_update_whitelist, check_whitelist_disabled) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // Force load of some policies. + std::set its_failed; + std::vector policy_elements; + std::set input { utility::get_policies_path() + configuration_file }; + utility::read_data(input, policy_elements, its_failed); + + // Check if the load worked. + ASSERT_EQ(its_failed.size(), 0); + + std::vector user_ids; + utility::get_policy_uids(policy_elements.at(0), user_ids); + + std::vector services; + utility::get_policy_services(policy_elements.at(0), services); + + // Add a security whitelist with check_whitelist disabled. + utility::add_security_whitelist(policy_elements.at(0), user_ids, services, false); + + security->load(policy_elements.at(0)); + + std::shared_ptr policy(std::make_shared()); + + vsomeip::service_t its_service(valid_service_id); + vsomeip::service_t its_invalid_service(invalid_service_id); + + boost::icl::discrete_interval its_instances(0x1, 0x2); + boost::icl::interval_set its_methods; + its_methods.insert(boost::icl::interval::closed(0x01, 0x2)); + boost::icl::interval_map> + its_instances_methods; + its_instances_methods += std::make_pair(its_instances, its_methods); + + // Add a valid request to the policy. + policy->requests_ += + std::make_pair(boost::icl::discrete_interval( + its_service, its_service, boost::icl::interval_bounds::closed()), + its_instances_methods); + + ASSERT_TRUE(security->is_policy_removal_allowed(valid_uid)) + << "The whitelist is disabled, a valid uid should be allowed to be removed"; + + ASSERT_TRUE(security->is_policy_removal_allowed(invalid_uid)) + << "The whitelist is disabled, an invalid uid should be allowed to be removed"; + + ASSERT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "The whitelist is disabled, a valid service_id should be allowed to be updated"; + + // Add an invalid request to the policy. + policy->requests_ += std::make_pair(boost::icl::discrete_interval( + its_invalid_service, its_invalid_service, + boost::icl::interval_bounds::closed()), + its_instances_methods); + + ASSERT_TRUE(security->is_policy_update_allowed(valid_uid, policy)) + << "The whitelist is disabled, a valid service_id should be allowed to be updated"; +} diff --git a/test/unit_tests/security_tests/ut_remove_client_to_sec_client_mapping.cpp b/test/unit_tests/security_tests/ut_remove_client_to_sec_client_mapping.cpp new file mode 100644 index 0000000..3aff27a --- /dev/null +++ b/test/unit_tests/security_tests/ut_remove_client_to_sec_client_mapping.cpp @@ -0,0 +1,41 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include "../../common/utility.hpp" + +namespace +{ +vsomeip_v3::client_t client = 10; +vsomeip_v3::uid_t uid = 4003030; +vsomeip_v3::gid_t gid = 4003032; +} + +TEST(remove_client_to_sec_client_mapping, check_no_policies_loaded) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + vsomeip_sec_client_t its_sec_client = utility::create_uds_client(uid, gid); + + // client and uid_gid should not be stored yet + EXPECT_FALSE(security->get_client_to_sec_client_mapping (client, its_sec_client)); + + // client and uid_gid should not be stored yet + EXPECT_FALSE(security->remove_client_to_sec_client_mapping(client)); + + // add client and uid_gid mappings + security->store_client_to_sec_client_mapping(client, &its_sec_client); + security->store_sec_client_to_client_mapping(&its_sec_client, client); + + // client and uid_gid mapping should be returned + EXPECT_TRUE(security->get_client_to_sec_client_mapping(client, its_sec_client)); + + // client and uid_gid mapping should be in the vector and able to be removed + EXPECT_TRUE(security->remove_client_to_sec_client_mapping(client)); + + // client and uid_gid should be removed from the vector + EXPECT_FALSE(security->get_client_to_sec_client_mapping(client, its_sec_client)); +} diff --git a/test/unit_tests/security_tests/ut_remove_security_policy.cpp b/test/unit_tests/security_tests/ut_remove_security_policy.cpp new file mode 100644 index 0000000..b3d6770 --- /dev/null +++ b/test/unit_tests/security_tests/ut_remove_security_policy.cpp @@ -0,0 +1,61 @@ +// Copyright (C) 2022 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include + +#include "../../common/utility.hpp" + +namespace { +vsomeip_v3::uid_t invalid_uid = 1; +vsomeip_v3::uid_t valid_uid = 4002200; +vsomeip_v3::gid_t invalid_gid = 1; +vsomeip_v3::gid_t valid_gid = 4003014; +} + +TEST(remove_security_policy_test, check_no_policies_loaded) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // no policies loaded -> remove_security_policy will return true independent of the uid or gid + EXPECT_FALSE(security->remove_security_policy(valid_uid, valid_gid)); + EXPECT_FALSE(security->remove_security_policy(invalid_uid, valid_gid)); + EXPECT_FALSE(security->remove_security_policy(valid_uid, invalid_gid)); + EXPECT_FALSE(security->remove_security_policy(invalid_uid, invalid_gid)); +} + +TEST(remove_security_policy_test, check_policies_loaded) +{ + std::unique_ptr security(new vsomeip_v3::policy_manager_impl); + + // force load of some policies + std::set its_failed; + std::vector policy_elements; + std::vector dir_skip; + utility::read_data(utility::get_all_files_in_dir(utility::get_policies_path(), dir_skip), + policy_elements, its_failed); + + for (const auto &e : policy_elements) + security->load(e, false); + + // check if the load worked + ASSERT_TRUE(policy_elements.size() > 0); + ASSERT_TRUE(its_failed.size() == 0); + + // the check_credentials_ and the policy_enabled_ variables should be set to true + ASSERT_FALSE(security->is_audit()); + ASSERT_TRUE(security->is_enabled()); + + // invalid uid and gid -> remove_security_policy must return false + EXPECT_FALSE(security->remove_security_policy(invalid_uid, invalid_gid)); + + // invalid uid and valid gid -> remove_security_policy must return false + EXPECT_FALSE(security->remove_security_policy(invalid_uid, valid_gid)); + + // valid uid and invalid gid -> remove_security_policy must return false + EXPECT_FALSE(security->remove_security_policy(valid_uid, invalid_gid)); + + // valid uid and gid -> remove_security_policy must return true + EXPECT_TRUE(security->remove_security_policy(valid_uid, valid_gid)); +} diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 17003a5..8756f3f 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -3,8 +3,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -cmake_minimum_required (VERSION 2.8...3.23.2) - # vsomeip_ctrl add_executable(vsomeip_ctrl EXCLUDE_FROM_ALL vsomeip_ctrl.cpp) target_link_libraries(vsomeip_ctrl diff --git a/vsomeip.pc.in b/vsomeip.pc.in index 9049c80..f717a12 100644 --- a/vsomeip.pc.in +++ b/vsomeip.pc.in @@ -8,4 +8,3 @@ Description: New SOME/IP stack, feature complete Version: @VSOMEIP_VERSION@ Libs: -L${libdir} -lvsomeip Cflags: -I${includedir} - diff --git a/vsomeip3.pc.in b/vsomeip3.pc.in index 27888e7..fa54522 100644 --- a/vsomeip3.pc.in +++ b/vsomeip3.pc.in @@ -8,4 +8,3 @@ Description: New SOME/IP stack, feature complete Version: @VSOMEIP_VERSION@ Libs: -L${libdir} -lvsomeip3 Cflags: -I${includedir} - -- cgit v1.2.1